文章目錄
- 【Compression】
- 【在IIS中配置Compression】
- 【Content Expirations】
- 【在IIS中配置Content Expirations】
- 【去掉沒必要的Http header】
【概述】
在這一章節,我們的主題聚焦在基礎設施建設上。
- Http Compression(壓縮)
- Content Expirations (內容到期)
- Content Distribution Networks - CDN(內容分髮網絡)
- Etags (E標籤)
- 去掉沒必要的Http header
【Compression】
我們前邊提到過,效能規則中的一條就是在伺服器和瀏覽器之間傳輸的資料越少越好。介於此規則,我們可以使用一個比較成熟的技術:Http Compression。
- Server 端會評估用戶端發來的http request中header裡的"Accept-Encoding”。來確定用戶端是否能處理壓縮過的資料。如果支援,server端會去對資料進行壓縮並返回結果到用戶端。
- 在keynote這個第三方服務評估的結果是,可以平均節省53%的頻寬,,網站平均快了25%。
- 現在IIS也提供這種技術的支援(免費的)
IIS7 對 compression 的支援
- 支援配置當cpu佔用率過高時,自動停止使用
- 預設最小的檔案大小是256k。
- 預設啟動靜態內容的壓縮
如果你對IIS 使用compression 感興趣。可以參見:http://weblogs.asp.net/owscott/archive/2004/01/12/57916.aspx
【在IIS中配置Compression】
開啟IIS。選中一個你的網站。在右邊選項卡裡選擇壓縮(compression)
也許有的朋友會發現,動態壓縮是灰色的。其實是我們沒安裝動態壓縮模組。我使用的是win7。安裝方法如下:
控制台-》程式-》開啟或關閉windows功能-》Internet 資訊服務-》全球資訊網服務-》效能功能(猥瑣)-》動態內容壓縮
如果是win server版本的朋友需要:
-
- Administrative Tools | Server Manager。
- 展開Roles,點擊Web Server(IIS)。
- 滾動到Role Services,點擊Add Role Services,開啟Add Role Services嚮導。
- 在Select Role Services頁面,滾動到Performance,選擇Dynamic Content Compression,選擇下一步。
現在我們還用第一章裡用到的那個網站做測試。開啟fiddler。
記下每個檔案的大小。返回到IIS,開啟動態壓縮和靜態壓縮。現在IIS 再接收到請求我的js和css檔案時。它先會判斷是否已經壓縮過唄請求的檔案。如果沒有它會進行壓縮,並且儲存到某一個目錄。其他使用者同樣請求相同的檔案時,它直接擷取壓縮過的檔案即可。
現在我們回到fiddler看看結果吧。
jquery 檔案從236K被壓縮到90k。其他js和css檔案也都受到相應的壓縮。
現在我們再使用上一章的另一把利器microsoft network monitor觀察壓縮前和壓縮後 來看看發生了什麼變化。
壓縮前:
壓縮後:
非常容易使用 MS Network monitor 對比出。壓縮前後,frame的數目明顯的減少了,從40條減少到9條。
由於95%以上的請求都會被詢問是否啟用compression。所以主流的瀏覽器都支援compression。
啟用compression會佔用少許的cpu。IIS7 對這一塊做了最佳化。
為了確保壓縮沒有使CPU超載,IIS7每30秒計算平均CPU利用率。當CPU利用率超過一個限制時,它會自動關閉壓縮。當CPU利用率低於限制時, 它會重新啟用壓縮。
限制的預設值是:
| |
關閉壓縮 |
重啟壓縮 |
| 動態檔案 |
90% |
50% |
| 靜態檔案 |
100% |
50% |
注意這意味著如果伺服器上的CPU一直在50%以上,但偶然高於90%,動態檔案壓縮會被關閉,但再也不會重新開啟了。
可以通過修改applicationHost.config檔案修改這些限制,通常它在C:\Windows\System32\inetsrv\config檔案夾下。
找到<httpCompression>節。
2.修改httpdynamicCompressionEnableCpuUsage屬性:<httpCompressiondynamicCompressionEnableCpuUsage="70".... >
3.重啟IIS。
【Content Expirations】
回顧一下我們第一張講過的效能規則。有一條是儘可能不經常地傳輸資料。
一個使用者訪問我網站的首頁,他會得到我的js,css和圖片等檔案。瀏覽器則替他儲存到本地的緩衝中。過了幾天使用者又來訪問我的網站了。伺服器還會看看瀏覽器緩衝中有木有他要的檔案。如果有的話,它會告訴server。我有這個檔案。但是我想知道它的版本是不是最新的。伺服器會看看這個檔案到底改沒改。如果改了,伺服器會發送新的檔案。如果沒,伺服器會返回給瀏覽器狀態代碼304。濤聲依舊。
304.沒改。
利用瀏覽器緩衝:
- 對於content folder 設定到期時間
- 盡量避免請求不經常改動的檔案
- 重新命名檔案,如果需要重寫瀏覽器緩衝(版本號碼/時間戳記)
【在IIS中配置Content Expirations】
開啟IIS。選中你的網站。選中scripts檔案夾(裝js的地方。如果有的話)在視圖選項卡裡找到HTTP 響應標題並進入。
右上方,設定常用標題-》使web內容到期。我們設定5天吧。這時候訪問我們的網站。使用fiddler 觀察結果如下:
那個max-age 我們算算 。正好是5天:)現在我們再開啟IE。internet選項-》瀏覽歷程記錄-》設定-》查看檔案
找到我們的js檔案。查看屬性,8月7號到期,正好5天:)
【CDN】
另一個對於提高網站效能有效辦法就是使用CDN了。
CDN的全稱是Content Delivery Network,即內容分髮網絡。其基本思路是儘可能避開互連網上有可能影響資料轉送速度和穩定性的瓶頸和環節,使內容傳輸的更快、更穩定。通過在網路各處放置節點伺服器所構成的在現有的互連網基礎之上的一層智能虛擬網路,CDN系統能夠即時地根據網路流量和各節點的串連、負載狀況以及到使用者的距離和回應時間等綜合資訊將使用者的請求重新導向離使用者最近的服務節點上。其目的是使使用者可就近取得所需內容,解決 Internet網路擁擠的狀況,提高使用者訪問網站的響應速度。
在這裡我只做簡單介紹,需要瞭解更詳細資料,請參見:http://en.wikipedia.org/wiki/Content_delivery_network
看到這裡讀者肯定會說我屌絲了。不解釋還廢話那麼多幹什嗎?CDN都是大公司用的和我們有關係嗎?
下面我來講講我們可以利用到的CDN:
JQuery是現在最流行的js library之一。google、microsoft、jquery.com都免費host了jquery庫在它們的cdn上。請看:
我在這裡可以使用我們自己的伺服器上的jquery檔案。也可以選擇從google、微軟和jquery官網的cnd來讀。即可以給自己伺服器減少壓力。也可以利用cnd加快讀取速度。
【ETags】
什麼是ETags?Etag的全稱是 entity tag。ETag實際上是一個hash+changeNumber組成的值。hash由檔案內容產生。IIS7中changeNumber預設是0;
本章前邊內容提到,我們通過設定內容到期,利用瀏覽器緩衝達到效能最佳化的效果,會使用expires headers告訴瀏覽器,不用再發送條件GET請求給伺服器啦,直接用緩衝裡面的資料就可以啦,從而加快訪問速度。
Etags 使用過程如下:
- 用戶端請求一個資源source 。
- 伺服器返回頁面souce,並在給source加上一個ETag。
- 用戶端展現該頁面,並將頁面連同ETag一起緩衝。
- 客戶再次請求資源source,並將上次請求時伺服器返回的ETag一起傳遞給伺服器。
- 伺服器檢查該ETag,並判斷出該頁面自上次用戶端請求之後還未被修改,直接返迴響應304(未修改——Not Modified)和一個空的響應體。
從此看來Etag有可能會誤導瀏覽器,讓瀏覽器忽略緩衝重複下載相同的檔案。
我們試著從刪除ETAG。
先看看沒刪除之前ETAG長什麼樣?
using System;using System.Collections.Generic;using System.Linq;using System.Web;/// <summary>/// Summary description for ETagRemoveModule/// </summary>public class ETagRemoveModule : System.Web.IHttpModule{ public ETagRemoveModule() { // // TODO: Add constructor logic here // } public void Dispose() { } public void Init(HttpApplication context) { context.EndRequest += new EventHandler(HandlerEndRequest); } public void HandlerEndRequest(Object sender, EventArgs e) { System.Web.HttpContext.Current.Response.Headers.Remove("ETag"); }}
<system.webServer> <modules> <add name="ETagRemoveModule.cs" type="ETagRemoveModule"/> </modules> </system.webServer>
ETags就沒啦:)
【去掉沒必要的Http header】
我們使用fiddler 可以看到,http response header 包含了很多資訊。
但是有些資訊是沒必要展示給使用者看的。比如我們使用了.netframework 4.0.我們使用IIS7.5。
首先它是多餘的資訊。其次它也有可能被一些駭客利用。
所以我們修改一下我們的代碼:
public void HandlerEndRequest(Object sender, EventArgs e) { HttpResponse oResponse = System.Web.HttpContext.Current.Response; if (null != oResponse) { oResponse.Headers.Remove("X-AspNet-Version"); oResponse.Headers.Remove("Server"); oResponse.Headers.Remove("ETag"); } }
現在我們的header乾淨多了,也安全多了。
下一章會介紹【前端效能】
參考文獻:
http://technet.microsoft.com/en-us/library/cc730629.aspx
http://weblogs.asp.net/owscott/archive/2004/01/12/57916.aspx
http://www.infoq.com/cn/articles/etags
http://www.webusability.cn/what-is-etag-howto-remove-etags-iis6-iis7-759/
http://en.wikipedia.org/wiki/Content_delivery_network