ASP.NET效能最佳化之讓瀏覽器緩衝動態網頁的方法

來源:互聯網
上載者:User

OutputCache是針對所有訪問伺服器資源的使用者,本篇要介紹的瀏覽器緩衝則是針對單個使用者,讓瀏覽器在我們的控制下徹底不持續訪問伺服器上的動態內容,也就是我們要讓瀏覽器變成我們的緩衝機制中的一部分,在某些特定的情境下最大化地提升ASP.NET網站的效能。如果說OutputCache是從廣度上提升並發效率,則瀏覽器緩衝是從深度上提升效率。

一:HTTP頭簡介

1.1瀏覽器第一次請求

假設我們請求一個URL地址,譬如我伺服器上的一個靜態頁面http://192.168.0.77/luminji2/html/test1.htm,會返回如下的HTTP頭資訊:

HTTP頭資訊中每個參數的含義這裡暫且不表,我們關注和本文論述相關的3個資訊:

首先,響應狀態200OK,即表示從伺服器上抓取資料成功。

其次,Last-Modified:Fri, 09 Sep 2011 02:56:45 GMT

這是WEB伺服器在告訴瀏覽器,我這個檔案的最後修改日期是Fri, 09 Sep 2011 02:56:45 GMT。必須要說明的是,它是GMT時間,也就是格林威治時間,一般中國境內使用的是GMT+8時區(要看系統的地區設定而定)。

最後就是Etag,WEB伺服器當前響應的這個對象的標誌值,就一個對象而言,比如一個 html 檔案,如果被修改了,其 Etag 也會別修改。

1.2什麼是瀏覽器緩衝

我使用的是FireFox,在地址欄內敲入about:cache?device=disk,我們就會看到被瀏覽器緩衝起來的上面這個HTML頁面,如下:

(注意,這裡的Last Modified和Http頭中的Last-Modified沒有任何關係)。

每種瀏覽器都會有自己的緩衝機制,但是都差不多,這裡暫且不表。

1.3如何命中緩衝

再次請求剛才的URL,我們得到頭資訊如下:

可以看到狀態變為304 Not Modified了,這相當於是WEB伺服器告訴瀏覽器,請用自己的緩衝,不要到我這裡來下載本文內容。那麼,WEB伺服器是根據什麼來決定這樣告訴瀏覽器呢?

這裡,我們就需要要求標頭資訊中的If-Modified-Since。要求標頭是瀏覽器發送給WEB伺服器的,一旦包含這個參數,就是瀏覽器跟WEB伺服器說:請查看自從Fri, 09 Sep 2011 02:56:45 GMT一來,你的內容變動過沒。WEB伺服器就會根據這個來判斷,如果沒有變動過,就會給瀏覽器返回304 Not Modified,就像本例。這樣子,瀏覽器就會去本地拿本文資料,減少了網路流量。

If-None-Match就是Etag判斷模式,跟Last-Modified其實完成的目的是一致的,這裡暫且不表。

假設我們修改了檔案test1.htm,試想會是什麼結果,肯定是200OK。瀏覽器和WEB伺服器之間就是通過這種機制來完成靜態網頁的緩衝。

二:asp.net的瀏覽器緩衝實現

上面我們說的是靜態頁面的情況,那麼aspx頁面,也就是動態網頁面會是怎麼樣一種情況?現在,我們建立一個動態網頁來看一看。先來建立一個最簡單的aspx,如下:

複製代碼 代碼如下:<body>
<%=DateTime.Now %>
</body>

請求一下,得到的頭資訊如下:

然後再多次請求一下,我們發現每次都是200OK,並且我們發現頭資訊中丟了一個很重要的資訊,那就是Last-Modified。伺服器沒有告訴瀏覽器自己的對象的最後修改日期,那麼瀏覽器就只好每次去伺服器重新擷取全部資料了。看到這裡,我們應該明白了,要讓瀏覽器不去拿資料,動態程式就得想法設法自己添加這個頭資訊。

好的,現在我們就在ASPX的後台代碼中這樣來實現一個最簡單的頭資訊添加:

複製代碼 代碼如下:protected void Page_Load(object sender, EventArgs e)
{
this.Response.AddHeader("Last-Modified", DateTime.Now.ToString("U", DateTimeFormatInfo.InvariantInfo));
}

添加了頭資訊後,我們發現再次請求URL後,頭資訊變為如下:

可以欣喜滴看到,回應標頭中包含了Last-Modified,而要求標頭中則包含了If-Modified-Since。

當然,我們仍舊發現,每次請求還是200OK。這是當然了,既然頭資訊都是ASP.NET在後台添加的,那麼我們要返回什麼樣的響應狀態給伺服器這段邏輯也得由自己來寫。現在,我們假設我們要讓瀏覽器緩衝10秒的時間長度,其完整的代碼應該如下:

複製代碼 代碼如下:protected void Page_Load(object sender, EventArgs e)
{
this.Response.AddHeader("Last-Modified", DateTime.Now.ToString("U", DateTimeFormatInfo.InvariantInfo));
DateTime IfModifiedSince;
if (DateTime.TryParse(this.Request.Headers.Get("If-Modified-Since"), out IfModifiedSince))
{
if ((DateTime.Now - IfModifiedSince.AddHours(8)).Seconds < 10)
{
Response.Status = "304 Not Modified";
Response.StatusCode = 304;
return;
}
}
//其它
}

經過這次修改後,如果我們在10秒內持續請求該aspx頁面,則始終返回304狀態,也即瀏覽器不會去伺服器拿本文,只會在本地去讀取自己的緩衝,這樣一來,伺服器壓力自然就小了。如果我們10秒內不對伺服器請求這個頁面,則10秒後會返回200OK,即重新到伺服器拿頁面資料。

現在,用AB來類比100並發使用者進行1000次請求,得到的比較結果如下(注意,為了強化效果,我們在後台需要類比一些比較耗時的動作,比如讀取資料庫):

左邊是未做緩衝的aspx頁面,右邊是做了緩衝的aspx頁面,可以看到,吞吐率相差10倍之多。

提示,使用ab進行壓力測試的時候,需要加入If-Modified-Since的頭資訊,命令如下:

C:\>ab -n1000 -c100 -H "If-Modified-Since: Friday, 09 September 2011 09:35:23 GMT" http://192.168.0.77/luminji2/aspx/test1.aspx

本文代碼下載:MvcApplication320110909.rar

三:問題的提出

在上面的說到的瀏覽器緩衝實現中,瀏覽器通過和WEB伺服器的溝通協調機制來確定自己是否需要調用緩衝,這意味著動態程式仍舊需要處理來自用戶端的請求,如果有一種機制能夠讓瀏覽器不需要請求伺服器就能夠決定是否調用緩衝,就能徹底捨去伺服器處理這一環節。下一篇將繼續闡述這種機制。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.