生存在資訊爆炸的網頁程式設計師們應該都會遇到網站效能不佳的問題,然而網站效能不佳有多種原因,舉凡 Web Server 本身的效能問題、系統架構設計不良、後端資料庫負載過重及設計不良,Web Server 將網頁內容傳輸到使用者瀏覽器的網路傳輸問題等等,這些都是需要面對的問題,網路傳輸問題最簡單也最容易解決的就是降低Web Server傳輸到使用者瀏覽器的網頁內容大小,降低網頁內容大小也有多種方法,例如把HTML檔案的換行及不必要的空白字元移除,CSS 盡量設計共用架構不要使用 Inline,壓縮 Javascript 檔案,縮小引用的圖檔等,還有一個大部分 Web Server 如: WebSphere、APACHE、IIS 5.0 以上都支援的 GZIP HTTP 壓縮功能,不過你用壓縮功能一定要犧牲一些 CPU Time ,目前大部分入口網站也都使用此項功能來減少頻寬的使用率,有效的提高網頁瀏覽的速度,我的 E 政府 (www.gov.tw)、Yahoo(tw.yahoo.com) 等大型入口網站也都有使用 GZIP,這也說明了他是個很普遍的技術,如果想提升瀏覽速度的話,不妨盡快評估導入此功能。
我們可以使用 HttpWatch 工具來證明上述的網站使用了 Gzip 壓縮技術,左邊視窗的 Accept-Encoding 屬性表示瀏覽器有支援 Gzip,右邊視窗的 Content-Encoding 則表示目前的網頁內容有使用 Gzip 壓縮 :
1. 我的E政府 www.gov.tw
2. 台灣雅虎奇摩 tw.yahoo.com
3. 點部落(尚未使用任何壓縮,因此無Content-Encoding屬性)
我們現在就來了解一下如何在 IIS 6.0 上設定 Gzip,來壓縮靜態檔案及動態檔案,這裡的步驟應該有不少的 Blog 文章說明,不過我還是自己做個紀錄,以後就不需要到處去找資料了。
1. 開啟網際網路資訊服務(IIS)管理員,並勾選啟用直接 Metabase 編輯,如此就可以在修改 IIS Metabase 檔設定後,各網站便立即生效,不然就得在設定後執行 IISReset 這是 Production 正式機所不允許的。
2. 於 IIS 管理員選擇「網站」、「內容」、「服務」頁籤,勾選「壓縮應用程式檔案」、「壓縮靜態檔案」,暫存目錄的大小限制可依需求做設定,一般不建議限制,不然資料夾的使用空間可是需要隨時註意才行。
「壓縮應用程式檔案」- 就是開啟 IIS Server 端動態網頁的即時壓縮網頁資料內容,例如 : .asp、.aspx、.php、.jsp 等,IIS Server 並不會儲存這些動態檔所產生的網頁內容的壓縮副本,而是即時壓縮後將內容傳送給瀏覽器,所以他 比較耗 CPU Time 。
「壓縮靜態檔案」- IIS Server 會先檢查靜態檔案暫存目錄下,是否目前的 Request 檔的壓縮檔案,並檢查原檔是否已被修改過,若修改過則會重新壓縮該檔,然後將壓縮的檔案內容回傳給瀏覽器,靜態檔如: .htm、.html、.cs、.js 等。
其實 IIS Server在傳送給瀏覽器時,都會先檢查瀏覽器是否支援 GZip 壓縮功能,不然 IIS Server 如果傳送已壓縮過的網頁內容給瀏覽器時,瀏覽器不支援 Gzip 的話,將無法正常顯示網頁資料給使用者瀏覽。
3.新增一個網頁服務延伸,這裡便是以人工方式來擴充 IIS 的 ISAPI。
你必須留意到 ISAPI Extension 、ISAPI Filter 是不同的架構,不過他們的目的都是為了擴充 IIS 的功能,你可以參考 IIS 6.0 的應用程式執行糢式 會有一些說明。
4.接下來是 IIS metabase 檔的設定,此檔案是以 XML 格式儲存的,這是最重要的步驟,且必須小心每個設定的屬性值,不然會發生嚴重的系統錯誤,建議設定前先備份該檔案。
檔案的路徑預設是在 C:WindowsSystem32inetsrvMetaBase.xml ,你可以使用任何的文字編輯器來修改此檔案的 <IIsCompressionScheme /> ,不過我建議可以使用 IIS Metabase Explorer 工具(IIS 6.0 Resource Kit Tools)來協助編輯, 這樣比較不容易出錯。
在此你會發現我們編輯了兩個 <IIsCompressionScheme /> 不過他們是屬於不同的 HTTP 壓縮演算法,一個是 Deflate,一個是 Gzip,我們就順便設定這兩個,因為他們只是壓縮演算法不同而已。
<IIsCompressionScheme Location ="/LM/W3SVC/Filters/Compression/deflate"
HcCompressionDll="%windir%\system32\inetsrv\gzip.dll"
HcCreateFlags="0"
HcDoDynamicCompression="TRUE"
HcDoOnDemandCompression="TRUE"
HcDoStaticCompression="FALSE"
HcDynamicCompressionLevel="9"
HcFileExtensions="htm
html
txt
js
css
doc
txt
ptt
xls
htc"
HcOnDemandCompLevel="10"
HcPriority="1"
HcScriptFileExtensions="asp
exe
aspx
asmx
dll"
>
</IIsCompressionScheme>
<IIsCompressionScheme Location ="/LM/W3SVC/Filters/Compression/gzip"
HcCompressionDll="%windir%\system32\inetsrv\gzip.dll"
HcCreateFlags="1"
HcDoDynamicCompression="TRUE"
HcDoOnDemandCompression="TRUE"
HcDoStaticCompression="TRUE"
HcDynamicCompressionLevel="9"
HcFileExtensions="htm
html
txt
js
css
htc
doc
ptt
xls"
HcOnDemandCompLevel="10"
HcPriority="1"
HcScriptFileExtensions="asp
exe
aspx
asmx
dll"
>
</IIsCompressionScheme>
這裡提醒你的是 : 如果你的網站使用了 ASP.NET AJAX 的話,建議你不要壓縮 .axd 檔案,不然網頁很容易發生錯誤,因為,瀏覽器不見得支援解壓縮 .axd,所以你必須做取捨的,不過,你可以在 ScriptManager 或 ToolkitScriptManager 控制項設定 ScriptMode="Release" 或 ScriptMode="Auto"(預設值) 搭配 Web.config 的 <system.web><compilation debug="false" defaultLanguage="c#" /></system.web> 設定,依經驗也可以達到 ASP.NET AJAX 一些檔案的壓縮效果。如果真的要壓縮網站的 .axd 檔,建議要做網站功能的回歸測試。<參考:縮減AJAX的axd內容大小>
Update 2009/02/11 : 使用 HttpWatch 針對 ASP.NET AJAX 的 WebResource.axd 及 ScriptResource.axd 側錄後發現,其實依照上述的設定後,會由 AJAX 的 HttpHandler 自動以 GZIP 壓縮上述兩個 .axd ,雖然你的網站可能不只這兩個 .axd 檔,但為了避免發生不可預期的問題,所以,建議盡量避免在 IIS 上又開啟 .axd 檔壓縮。
使用 IIS Metabase Explorer 編輯 :
我們變更了三個設定,若有需要的話請自行修改其他屬性值設定。
- HcFileExtensions-htm, html, txt , js, cs, htc, doc, ptt, xls
- HcDynamicCompressionLevel-9 (值越大壓縮效果越好,但越耗 CPU Time)
- HcScriptFileExtensions-asp, exe, aspx, asmx, dll
4. 設定完畢後須做網站的功能回歸測試以確保所有功能均正常運作,若發現有在同一台 IIS Server 上有網站不能使用 Gzip 壓縮的話,也可單獨排除該網站不進行壓縮。
要關閉識別元為 132465789 網站的靜態壓縮功能這邊提供兩種方法,另外你也可以直接修改 Metabase.xml 檔:
- 你可以使用指令方式設定該網站的 DoStaticCompression 屬性為 0 (False),Usertype屬性為 file 。
cscript C:InetpubAdminScriptsadsutil.vbs set w3svc/123465789/root/DoStaticCompression False
- 使用 IIS Metabase Expolorer 來新增一個 DoStaticCompression DWORD
要關閉識別元為 132465789 網站的動態壓縮功能這邊提供兩種方法,另外你也可以直接修改 Metabase.xml 檔:
- 你可以使用指令方式設定該網站的 DoDynamicCompression 屬性為 0 (False),Usertype屬性為 file 。
cscript C:InetpubAdminScriptsadsutil.vbs set w3svc/123456789/root/DoDynamicCompression False
- 使用 IIS Metabase Expolorer 來新增一個 DoDynamicCompression DWORD
總結
我試過一些熱心網友分享或是 Open Source 的應用 GZIP 的 ASP.NET HTTPModule 來壓縮 ASP.NET AJAX 網站的網頁資料內容,
例如: Code Project 的 HTTP Compression Module 此功能可壓縮 WebResource.axd 檔,但是,在 .NET Framework 3.5 的 ASP.NET AJAX 環境測試依然有部分網頁來是會產生錯誤,
因此,我還是放棄對 axd 檔的壓縮,畢竟很少有解決方案是能夠百分百滿足需求的,依 80 / 20 法則,我認為我所使用的 IIS 啟用 GZIP 壓縮,
並搭配 ASP.NET AJAX 的 ScriptMamager 、 ToolkitScriptManager 的 ScriptMode 屬性設定為 Release 方法已經足夠,所以,在此分享經驗給大家參考。