Web前端性能優化教程05:網站樣式和腳本

本文是Web前端性能優化系列文章中的第五篇,主要講述內容:網站樣式和腳本代碼的放置位置、使用外部javascript和css。完整教程可查看:Web前端性能優化

一、將樣式表放在頂部

可視性回饋的重要性

進度指示器有三個主要優勢它們讓用戶知道系統沒有崩潰,隻是正在為他或她解決問題;它們指出瞭用戶大概還需要等多久,以便用戶能夠在漫長的等待中做些其他事情;最後,它們能給用戶提供一些可以看的東西,使得等待不再是那麼無聊。最後一點優勢不可低估,這也是為什麼推薦使用圖形進度條而不是僅僅以數字形式顯示預期的剩餘時間。在Web的世界裡,Html頁面的逐步呈現就是很好的進度指示器。

將沒有立即使用的css放在底部是錯誤的做法

通常組件的下載是按照文檔中出現的順序下載的,所以將不需要立即使用到的組件css(比如需要用戶點擊登錄彈出框需要用到的樣式)放在底部,可以得到一個加載很快的頁面。然而這個推論其實是錯誤的,IE8以下(包括IE8)的工作方式是如果css表仍在加載,構建呈現樹就是一種浪費,因為在所有樣式表加載並解析完畢之前無需繪制任何東西,這時整個瀏覽器顯示都是空白,直到css加載完畢,這就失去瞭提供可視化回饋的機會,讓用戶感覺到緩慢。

不過,更高級版本的IE和其他瀏覽器已經克服瞭白屏問題,所以這種情況已經不復存在。

無樣式內容的閃爍

這裡將討論另外一種出現的情況,當我們將css放在底部,頁面可以正常逐步呈現,但在css下載並解析完畢之後,已經呈現的文字和圖片就要用新的樣式重繪瞭,這就是無樣式內容的閃爍,這將是一種不好的用戶體驗。

CSS的最佳擺放位置

使用LINK標簽將樣式表放在文檔HEAD中。

二、將腳本放在底部

並行下載

瀏覽器下載組件的時候並不是每次隻下載一個組件,而是實現瞭並行下載的機制。HTTP規范1.1建議瀏覽器從每個主機名並行地下載兩個組件。既假如頁面的所有組件都來自於一個主機名,則每次隻能同時下載兩個組件。如果組件使用瞭兩個主機名,而且組件的主機名分配均勻,則每次並行下載的數量變成瞭2*2=4。不過,當代的瀏覽器普遍實現都超過瞭2個並行下載,不同的瀏覽器設置都有所不同。

腳本阻塞下載

並行下載組件能加快頁面的加載速度,然而,在下載腳本的時候並行下載實際上是被禁用的,即使其他組件使用瞭不同的主機名,瀏覽器也不會啟動其他的下載。原因如下:1. 腳本可能使用瞭document.write來修改頁面內容,因此瀏覽器會等待,以確保能夠恰當地佈局;2. 為瞭保證腳本能夠按照正確的順序執行,如果並行下載多個組件,就無法保證響應是按照特定順序到達瀏覽器的。

所以,腳本放在越靠近頂部的地方將越延遲用戶的可視化反饋,這不是一種良好的用戶體驗,會讓用戶感覺到緩慢。

最佳做法

放置腳本的最好地方是頁面的底部,這不會阻止頁面內容的呈現,而且頁面的可視化組件可以盡早下載。以博客園為例,博客園就把google流量分析的js放在底部,同時把下載Blog新聞和Blog側邊欄的js執行函數放在瞭底部。

三、使用外部javascript和css

基礎知識

頁面瀏覽量(PV):用戶對頁面請求訪問次數總和。

內聯 VS 外置

對於兩個相同大小的頁面,一個使用瞭內聯,隻有html需要下載,一個使用瞭外置,包括一個js和一個css,在用戶不帶緩存訪問頁面的時候,內聯所有的js和css的效率更快,原因是外置js和css帶來額外的http請求開銷,1個http請求相對於3個http請求要更快一些。盡管如此,現實中還是使用外部文件會產生較快的訪問速度,這是由於外部js和css有機會被瀏覽器緩存起來,當再次請求相同的js或css的時候,瀏覽器將不會發出http請求,而是使用緩存的組件,減少瞭總體需要下載文件的大小。

綜合來講,我們一般推薦使用外置的js和css,不過這也要根據自身web的訪問場景以及PV做出最優選擇。

如何劃分組件?

當我們決定使用外置js和css的時候,這時怎樣劃分js和css並打包到外部文件中成為一個首要考慮的問題。在典型情況下,頁面之間的js和css的重用既不可能100%重疊,也不可能100%無關。

一種極端的做法是創建一個單獨的,聯合瞭所有js的文件,再創建一個包含瞭所有css的文件。這隻要求用戶生成一個Http請求,但它增加瞭用戶不帶緩存訪問的情況下的數據量,同時我們必須清楚:緩存有時會失效,這將帶來更多額外的開銷。而且,在任何一塊獨立的js或css改變後,都需要更新文件,並發佈新的版本號,這將使所有客戶端的舊版本緩存失效。

另一種極端的做法是為每個頁面提供一組分離的外部文件,這種方式真正做到按需下載,但缺點在於每個頁面都產生令響應時間變慢的HTTP請求。

對於大多數web應用來說,我們需要一種折中的方案!將頁面劃分為幾種頁面類型,然後為每種類型創建單獨的js和css。以css為例,我們可以創建一個所有頁面都通用的global.css,再針對不同類型的頁面,創建對應的css。

完整教程可查看:Web前端性能優化