天天看點

前端優化的14條規則

前端性能優化的14個規則

作為一個半前端工程師,而且隻會寫點HTML5和CSS3的“假”前端工程師,為了能更好地了解一下前端的花花世界,最近拜讀了《高性能網站建設指南》一書,對作者提出的前端性能優化的14個規則獲益匪淺,為了讓自己印象更深刻點,決定作此文,當做學習筆記也好,知識總結也罷,總歸看過的東西要讓自己很好地掌握很好地運用起來才是王道。在解讀這些規則的同時,我會用我一年半多的移動網站開發經曆提出一些針對移動網站的優化建議。

規則01:盡量減少HTTP請求

前端優化的黃金準則指導着前端頁面的優化政策:隻有10%-20%的最終使用者響應時間花在接受請求的HTML文檔上,剩下的80%-90%時間花在為HTML文檔所引用的所有元件(圖檔、腳本、樣式表等)進行的HTTP請求上。是以,改善響應時間的最簡單途徑就是減少元件的數量,并由此減少HTTP請求的數量。當然很多人就會說,既然這樣,那我們就減少頁面元件的數量不就OK了嗎?那你試試,你會掀起一場性能優化和産品設計之間的大PK。是以,我們要減少HTTP請求是要平衡性能和設計的。如果找到這個平衡點呢?書中從以下幾個方面做了介紹,我逐一說明:

① 圖檔地圖

初看“圖檔地圖”四個字,對非專業的前端人員來說一頭霧水,我的第一印象就是這樣的,咱們以京東的移動站點為例,右側使用者和購物車的圖示,正常實作我會選擇如下方式:

<div class=”定義使用者icon顯示的樣式表”></div>
           
<div class=” 定義使用者icon顯示的樣式表”></div>
           

這種方式無可厚非的,但是兩張圖檔就有兩個HTTP請求,這明顯是增加了頁面中的HTTP請求。

那麼我們可以把這兩個HTTP請求變成一個嗎?答案當然是可以的,這就是圖檔地圖:允許在一張圖檔上關聯多個URL,而目标URL的選擇取決于使用者單擊了圖檔上的哪個位置。這樣上面京東兩個圖示合并成一張圖檔,這樣圖檔的HTTP請求就減少了一個。

示例代碼如下:

<img src=”合并後的圖檔”>

<map name=”map1”>

           <area shape=”rect” coords=”0,0,40,40” href=”使用者跳轉頁面URL”>

           <area shape=”rect” coords=”50,0,90,40” href=”購物車跳轉頁面URL”>

</map>
           

不過圖檔地圖隻支援矩形形狀,其他形狀不支援。

② 請CSS喝“雪碧”(CSS Sprites)

CSS Sprites一句話:将多個圖檔合并到一張單獨的圖檔,這樣就大大減少了頁面中圖檔的HTTP請求。

③ 内聯圖檔和腳本

使用data:URL(Base64編碼)模式直接将圖檔包含在Web頁面中而無需進行HTTP請求。

但是此種方法存在明顯缺陷:

  • 不受IE的歡迎;
  • 圖檔太大不宜采用這種方式,因為Base64編碼之後會增加圖檔大小,這樣頁面整體的下載下傳量會變大;
  • 内聯圖檔在頁面跳轉的時候不會被緩存。(大圖檔可以使用浏覽器的本地緩存,在首次通路的時候儲存到浏覽器緩存中,典型的是HTML5的manifest緩存機制以及LocalStorage等)。

④ 樣式表的合并

将頁面樣式定義、腳本、頁面本身代碼嚴格區分開,但是樣式表、腳本也不是分割越細越好,因為沒多引用一個樣式表就增加一次HTPP請求,能合并的樣式表盡量合并。一個網站有一個公用樣式表定義,每個頁面隻要有一個樣式表就OK啦。

通過以上四個努力之後,你會發現你的網頁響應時間最多能減少一半,這不是作者說大話,也不是我狂吹,我親手用我的移動網站首頁做了一個嘗試,本地測試之後響應時間能減少40%左右。是以減少頁面HTTP請求數量,是一個很重要的原則。遵循此原則可以同時改善首次通路和後續通路的響應時間,而每一個網站的首次響應時間會決定使用者之後還來不來的重要原因。

規則02:使用内容釋出網絡(CDN的使用)

什麼叫内容釋出網絡(CDN)?它是一組分布在多個不同地理位置的Web伺服器,用于更加有效地向使用者釋出内容。主要用于釋出頁面靜态資源:圖檔、css檔案、js檔案等。如此,能輕易地提高響應速度。

關于CDN的具體詳細原理以及優缺點,各位可以自行詢問度娘或者google。

規則03:添加Expires頭

浏覽器使用緩存來減少HTTP請求的資料,并減小HTTP響應的大小,使頁面加載更快。Web伺服器使用Expires頭來告訴浏覽器它可以使用一個元件的目前副本,直到指定的deadline為止。HTTP規範中稱此頭為:在這一時間之後響應被認為失效。

個人對這塊表示不想使用,其實就是一句話,把一些css、js、圖檔在首次通路的時候全部緩存到浏覽器本地,從我做移動網站的過程中發現,其實沒有這麼複雜,完全可以使用HTML5提供的本地緩存機制就OK了。關于HTML5本地緩存機制,各位可以查閱相關資料。後續我也會對HTML5的緩存機制進行介紹的。

規則04:壓縮元件(使用Gzip方式)

書中關于壓縮從gzip壓縮方式到如何壓縮講了很多,我想直接跳過,對于做PC網站或者移動網站來說,急需要壓縮的是css檔案和js檔案,至于如何壓縮,網上有很多線上工具,去挑選一個自己用的順手看的順眼的就好,當然也有人選擇對HTML進行壓縮,這樣也可以。但是實際工作中我沒有這麼做。之所謂沒有這麼做,是因為我覺得很麻煩。不要鄙視我,畢竟我不是一個真正意義上的前端工程師,哈哈!

規則05:将CSS樣式表放在頂部

如果将css樣式定義放在頁面中或者頁面底部,會出現短暫白屏或者某一區域短暫白闆的情況,這和浏覽器的營運機制有關的,不管頁面如何加載,頁面都是逐漸呈現的。是以在每做一個頁面的時候,用Link标簽把每一個樣式表定義放在head中。

規則06:将javascript腳本放在底部

浏覽器在加載css檔案時,頁面逐漸呈現會被阻止,直到所有css檔案加載完畢,是以要把css檔案的引用放到head中去,這樣在加載css檔案時不會組織頁面的呈現。但是對于js檔案,在使用的時候,它下面所有也頁面内容的呈現都會被阻塞,将腳本放在頁面越靠下的地方,就意味着越多的内容能夠逐漸呈現。

規則07:避免使用CSS表達式

CSS表達式是動态玩CSS的一種很強大的方式,但是強大的同時也存在很高的危險性。因為css表達式的頻繁求值會導緻css表達式性能低下。如果真想玩css表達式,可以選用隻求值一次的表達式或者使用事件處理來改變css的值。

規則08:使用外部javascript和CSS

内聯js和css其實比外部檔案有更快的響應速度,那為什麼還要用外部呢?因為使用外部的js和css可以讓浏覽器緩存他們,這樣不僅HTML文檔大小減少,而且不會增加HTTP請求數量。

另外,使用外部js和css可以提高元件的可複用性。

規則09:減少DNS查詢

DNS查詢有時間開銷,通常一個浏覽器查找一個給定主機名的IP位址需要20-120ms。

緩存DNS:緩存DNS查詢可以很好地提高網頁性能,一旦緩存了DNS查詢,之後對于相同主機名的請求就無需進行再次的DNS查找,至少短時間内不需要。

是以在使用頁面中URL、圖檔、js檔案、css檔案等時,不要使用過多不同的主機名。

規則10:精簡javascript

如何精簡?最初始的精簡方式就是移除不必要的字元減小js檔案大小,改善加載時間。包括所有的注釋、不必要的空白字元。

進階一點的精簡方式就是:混淆。它不但會移除不必要的字元,還會改寫代碼,比如函數和變量的名字會被改成很短的字元串,這樣使js代碼更簡練更難閱讀。

但是我一般很少使用混淆,一個現在網際網路時代,代碼沒有必要整的那麼神秘,大可以大家一起share,天下代碼一起抄,隻要抄出自己的特色就ok了。而且一旦使用混淆,對于js代碼的維護和調試都很複雜,因為有時候混淆之後的js代碼完全看不懂。

其實實際開發過程中,從檔案大小和代碼可複用性來說,不僅僅是js代碼需要精簡,css代碼一樣也很需要精簡。

規則11:避免重定向

重定向的英文是Redirect,用于将使用者從一個URL重新跳轉到另一個URL。最常見的Redirect就是301和302兩種。

關于重定向的性能影響這裡就不說了,自行查閱相關資料吧。

在我們實際開發中避免重定向最簡單也最容易被忽視的一個問題就是,設定URL的時候,最後的“/”,有些人有時候會忽略,其實你少了“/”,這時候的URL就被重定向了,是以在給頁面連結加URL的時候切記最後的“/”不可丢。

規則12:删除重複腳本

重複的js代碼除了有不必要的HTTP請求之外,還會浪費執行js的時間。

将你使用的js代碼子產品化,可以很好地避免這個問題,至于js子產品化如何實作,現在有很多可以使用的開源架構,我用的比較多的是我們公司玉伯的Sea.js。

規則13:配置ETag

Etag(Entity Tag),實體标簽,是Web伺服器和浏覽器使用者确認緩存元件的有效性的一種機制。

寫的很複雜,對我這種非專業的前端開發人員來說,有點過了,關于這個原則有興趣的自己看吧。

規則14:使Ajax可緩存

針對頁面中主動的Ajax請求傳回的資料要緩存到本地,當然這個是針對短期内不會變化的資料。如果不确定資料變化周期的話,可以增加一個修改辨別的判斷,我正常處理過程中會給一些Ajax請求傳回的資料增加一個MD5值的判斷,每次請求會判斷目前MD5是否變化,如果變化了取最新的資料,如果不變化,則不變。

14個規則啊,那我們開發過程中要針對這每一個規則對自己的前端代碼做check嗎?我反正不這麼幹,做前端頁面,尤其是移動網站的頁面,我所記住的準則就是:盡量減少頁面大小,盡量降低頁面響應時間。在頁面性能和互動設計之中找平衡點。