天天看點

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

介紹

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

延時有多糟糕

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

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

你可以通過使用CDN(Content Delivery

Network)來減少等待時間。然而,一個更好的解決方案是使用HttpHandler提供多個檔案的一次請求,該HttpHandler整合了數個檔案并且提供了一次輸出。是以,代之以許多的<scropt>或者<link>标簽,你隻需要寫一個<scropt>以及<link>标簽,并将它們标記在HttpHandler中。由你來告訴handler哪些檔案需要被整合,并且它提供了哪些檔案的一次輸出。這省去了從浏覽器發出許多請求産生的延時。

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

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

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

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

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

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

HttpHandler讀取定義在一個配置檔案中的檔案名,整合所有的那些檔案,并将它們一次響應到用戶端。它通過gzip來壓縮響應内容以此節約帶寬。另外它提供一個帶有cache的響應請求頭來緩存響應到浏覽器的Cache裡,使得浏覽器對之後的通路不需要再次請求它。

在請求參數中,你可以用“S”參數辨別檔案集合的名稱,然後用“t”參數來辨別content

type,然後使用“v”參數來辨別一個版本。因為響應被緩存了,如果你修改了檔案集合中的任何一個,你将不得不增加參數“v”的值來讓浏覽器再次下載下傳響應。

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

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

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

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

使用HttpHandler整合器的例子

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

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

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

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

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

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

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

這裡列出了Handler如何工作:

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

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

(3) 它讀取每一個檔案,然後将它們緩存在緩沖區中

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

(5) 被壓縮後的緩沖區内的内容将被發送到浏覽器

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

Handler帶來的好處:

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

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

HttpHandler如何工作

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

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

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

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

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

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

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

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

WriteBytes方法有許多技巧在裡面。它提供了一個基于是否位元組是壓縮格式的響應頭。然後它提供了一個緩存辨別頭,讓浏覽器緩存響應内容。

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

怎樣使用這個handler呢?

包含HttpCombiner.ashx在你的項目中

定義檔案集合在你的web.config配置檔案的<appSettings>節點中

改變的<link>與<script>标簽,使用HttpCombiner.ashx需要的格式:HttpCombiner.ashx?s=<setName>&t=<contentType>&v=<versionNo>

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

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

原文釋出時間為:2011-10-02

繼續閱讀