asp.net使用httphandler打包多CSS或JS檔案以加快頁面載入速度

來源:互聯網
上載者:User

介紹

使用許多小得JS、CSS檔案代替一個龐大的JS或CSS檔案來讓代碼獲得更好的可維護性,這是一個很好的實踐。但這樣做反過來卻損失了網站的效能。雖然你應該將你的Javascript代碼寫在小檔案中並且將大的CSS檔案分割到小檔案中,當一個瀏覽器請求那些JS以及CSS檔案,它卻將為每一個檔案產生一個請求。每一個HTTP請求將導致從你的瀏覽器到伺服器上的一次“往返”,從響應伺服器到用戶端瀏覽器之間的等待時間稱之為“延時”。因此,如果你有四個JS檔案以及三個CSS檔案需要被頁面載入,你將要等待七次網路上的“往返”。在本國內,延時平均為70ms。所以總延時為490ms,大概半秒鐘。而來自國外的訪問,平均延時大概在200ms左右。因此,那意味著1400ms的時間浪費。而直到CSS與JS檔案被完全載入,頁面才會被完全地顯示出來。所以,越長時間的延時,頁面載入地越慢。

延時有多糟糕

這裡有一張圖片顯示了,每一個請求怎樣產生了“延時”,這些“延時”累加起來顯著地影響了頁面的載入:


你可以通過使用CDN(Content Delivery Network)來減少等待時間。然而,一個更好的解決方案是使用HttpHandler提供多個檔案的一次請求,該HttpHandler整合了數個檔案並且提供了一次輸出。所以,代之以許多的<scropt>或者<link>標籤,你只需要寫一個<scropt>以及<link>標籤,並將它們標記在HttpHandler中。由你來告訴handler哪些檔案需要被整合,並且它提供了哪些檔案的一次輸出。這省去了從瀏覽器發出許多請求產生的延時。


這裡你能看到如果你把多個JS檔案以及CSS檔案整合到一個輸出裡,有怎樣的效能提升。

在通常的網頁中,你將看到很多的JS引用:


而我們可以僅用一個<script>標籤請求整個JS檔案的集合,來代替這裡的每一個<script>標籤:


HttpHandler讀取定義在一個設定檔中的檔案名稱,整合所有的那些檔案,並將它們一次響應到用戶端。它通過gzip來壓縮響應內容以此節約頻寬。另外它提供一個帶有cache的響應要求標頭來緩衝響應到瀏覽器的Cache裡,使得瀏覽器對之後的訪問不需要再次請求它。

在請求參數中,你可以用“S”參數標識檔案集合的名稱,然後用“t”參數來標識content type,然後使用“v”參數來標識一個版本。因為響應被緩衝了,如果你修改了檔案集合中的任何一個,你將不得不增加參數“v”的值來讓瀏覽器再次下載響應。

使用該HttpHandler,你可以這樣來請求CSS檔案:


這裡列出了你將需要怎樣來定義請求的集合,在web.config中:


使用HttpHandler整合器的例子

我構建了一個簡單的測試網站來向你展示它的使用,該測試網站有兩個CSS以及JS檔案。Default.aspx僅使用一個<link>和<script>標籤通過HttpCombiner.ashx來請求它們。


下面是Default.aspx檔案的內容:


就像你看到的那樣,有一個<link>標籤向HttpCombiner.ashx發送了一個請求並提供了請求集合的名稱——Set_Css,當然還有一個<script>標籤請求了一個Set_Javascript的集合。

上面的兩個集合都被定義在web.config檔案中:


這裡列出了Handler如何工作:

(1)    首先,它會從“s”參數中讀取檔案集合的名稱

(2)    然後它從web.config檔案中拿到集合的定義

(3)    它讀取每一個檔案,然後將它們緩衝在緩衝區中

(4)    緩衝區然後通過gzip進行壓縮

(5)    被壓縮後的緩衝區內的內容將被發送到瀏覽器

(6)    被壓縮後的緩衝區內的內容被儲存在ASP.NET緩衝中,以讓隨後的對相同集合的請求能夠直接地從Cache中擷取資料,而不是從檔案系統或外部的URL去讀取每一個檔案。

Handler帶來的好處:

(1)    它減少了網路上的“往返”次數,你把越多的檔案放到一個集合中,就越能減少網路延時,它提高了效能。

(2)    它緩衝了所有的整合過的壓縮響應,因此省去了一次又一次的讀取檔案系統並壓縮它。它提供了可擴充性。

HttpHandler如何工作

首先handler從請求字串中讀取集合名、類型以及版本:


如果要載入的檔案集合已經被緩衝了,那將直接從cache中寫入響應流。否則,檔案將被一個接一個地載入,然後被儲存在一個MemoryStream。MemoryStream被通過GzipStream壓縮(如果瀏覽器支援壓縮輸出)。


在整合了所有的檔案並壓縮後,被整合的位元組流被緩衝起來,以讓隨後的請求可以直接地從緩衝擷取資料。


GetFileBytes方法讀取一個檔案或者URL,然後返回位元組。所以,你可以在你的網站裡使用虛擬路徑,或者你可以使用URL指向一個宿主在另外的域中的Js/Css檔案。


WriteBytes方法有許多技巧在裡面。它提供了一個基於是否位元組是壓縮格式的回應標頭。然後它提供了一個緩衝標識頭,讓瀏覽器緩衝響應內容。


怎樣使用這個handler呢?

  • 包含HttpCombiner.ashx在你的項目中
  • 定義檔案集合在你的web.config設定檔的<appSettings>節點中
  • 改變的<link>與<script>標籤,使用HttpCombiner.ashx需要的格式:HttpCombiner.ashx?s=<setName>&t=<contentType>&v=<versionNo>
原文連結:http://www.codeproject.com/KB/aspnet/HttpCombine.aspx   原始碼: http://download.csdn.net/detail/yanghua_kobe/3654006

譯者注:今天在嘗試使用該技術時,遇到一個問題。那就是在打包壓縮CSS檔案時。如果檔案中涉及到圖片路徑(例如background-img的url屬性時)。無法正確請求圖片。原因是,通常這些圖片都使用的是相對路徑。瀏覽器通常情況下載擷取到CSS檔案後,會以CSS檔案本身作為參考,根據圖片的相對路徑來尋找圖片。而批量打包時,用來參考的路徑本身變成了handler的路徑,因而會導致尋找圖片的路徑出錯而無法下載。其實就算是人為將圖片的路徑設定成相對於本handler的相對路徑仍然無法下載!

解決方案:採用絕對路徑,但也取決於網站的發布方式。如果發布時建立的網站,那麼可以直接通過"/"來從根目錄開始表達CSS中的背景圖片的絕對路徑。因為建立網站時,可以直接用“/”來標識根目錄。而建立虛擬目錄時,則需要加入建立虛擬目錄的檔案夾名。如myweb,則絕對路徑表示為"/myweb/images......."這樣才能正確地擷取圖片。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.