在我們日常的網站開發工作中,一個頁面難免會引用到各種樣式及腳本檔案。了解Web開發的朋友們都知道,頁面引用的每一個:
<link href="style.css" rel="stylesheet" type="text/css">
或者:
<script type="text/javascript" src="jquery.js"></script>
都會由浏覽器向伺服器發出一個請求,伺服器傳回對應的内容供浏覽器渲染使用。對于稍微上點規模的網站,頁面中難免會嵌入大量樣式及腳本檔案,每個檔案動辄幾K,多辄幾十上百K大小,嚴重影響了頁面加載及渲染速度。再加之各低版本浏覽器請求并發數量的限制,我朝蝸牛一般的網速環境,使這種情況雪上加霜。
針對樣式及腳本檔案請求和加載方面的優化,正常的方式有以下幾種:
1,伺服器端利用第三方庫進行壓縮優化處理,同時Web伺服器開啟Gzip壓縮輸出。
該方式可以極大的減小網絡傳輸資料量,進而縮短用戶端資源加載時間。應用較廣。
參考各種第三方壓縮工作壓縮比及效率分析:
http://coderjournal.com/2010/01/yahoo-yui-compressor-vs-microsoft-ajax-minifier-vs-google-closure-compiler/
2,将頁面中次優先級的腳本檔案置于頁面底部。
我們知道,位于<head></head>區域的樣式及腳本檔案請求,會阻塞接下來頁面的加載,而很多時候,該區域的部分資源檔案并不是在頁面首次呈現時就用的上的。比如頁面中一些按鈕的點選處理、圖像特效、送出驗證及異步請求等。将這些“低優先級”的腳本檔案移到底部,避免了一些非必要阻塞,進而改善頁面的加載速度。這也是現在絕大多數站點使用的方法。
3,利用類似requirejs等第三方庫,實作腳本檔案的按需加載。
比如現在有一個頁面,首次加載的時候,我們隻下載下傳jquery檔案,隻有當使用者點選了頁面中的某一個按鈕,或者發起了一次異步請求,我們才加載另外一個function.js檔案。這就是所謂的按需加載。相關文章可以參考:
http://www.cnblogs.com/chenxizhang/archive/2013/05/16/3081941.html
該方法的缺點是需要對頁面資源檔案進行較高程度的子產品化,對開發人員要求較高。
4,利用内容分發網絡(CDN)加速。
由于主流浏覽器對于同一個域所允許保持的連接配接數都是有限制的,那麼,我們采用CDN的做法來将某些内容放在不同的域裡面,從一定意義上可以增加下載下傳的并行度。比如我們可以設定一台獨立的樣式或腳本檔案伺服器,與頁面檔案的域相區分,則可以利用CDN帶來的好處提高頁面加載速度。又比如頁面引用Google提供的jquery位址:
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>,
同樣可以縮短頁面加載時間,減少伺服器網絡流量。當然,利用CDN的缺點也是顯而易見的,硬體成本提升,請求節點增多導緻網絡出錯機率提升等。該方法常被一些大型網站采用。
5,人工将樣式或腳本檔案合并,輔以相關的優化壓縮手段輸出至頁面。
緻命的缺點是多個獨立的功能檔案揉合成一個整體之後,不便于功能維護,同時非智能的處理方式費時費力。該方法僅存在于理論的象牙塔中,無實際作用。
大道一條,功法千萬。本文在代碼層面提供了以下處理方式。以ASP.NET MVC架構為例:
(1),假如伺服器端存在資源檔案:A.js、B.js;A.css、B.css
(2),在View層。在需要添加腳本的地方,調用Html輔助方法:
Html.AppendFile(ResourceType.Script,"[A.js]"); //添加腳本檔案A.js
Html.AppendFile(ResourceType.Script,"[B.js]"); //添加腳本檔案B.js
或者:
Html.AppendFile(ResourceType.StyleSheet,"[A.css]"); //添加樣式檔案A.css
Html.AppendFile(ResourceType.StyleSheet,"[A.css]"); //添加樣式檔案B.css
另外,結合分組、優先級等手段,可以對資源檔案進行更加精準的控制。
(3),最終輸出的html檔案中,資源檔案請求格式為:
<script src="resource/style?href=[A,B]&compress" type="text/javascript"></script>
其中,最後的compress參數用來辨別是否進行壓縮。
(4),在 resource/style[script] 處理程式中,我們提取A,B腳本檔案内容,合并壓縮後輸出至用戶端。
以上方法帶來的好處是顯而易見的:
(1),自動實作了資源檔案的請求合并。未損失各個檔案的功能獨立性。
(2),我們在編寫伺服器端View層代碼的時候,其實與平常并無二緻。唯一的差別在于現在調用的是Html輔助方法。
(3),輔以伺服器端代碼壓縮,CDN等手段,可以極大的改善用戶端頁面加載速度。
接下來,鄙人将在ASP.NET MVC架構下,從零開始一步一步實作上述處理流程,最終給出一套完整的代碼方案以供各位參考。