前端最佳化,這幾字對於做網站的人來說應該相當熟悉了。
近年來,前端的使用者體驗現在顯得越來越重要,從後台開發,到前台技術很多工作都圍繞如何提高前端使用者體驗而展開。我們也許能從這篇文章裡擷取一些有用的資訊,用到自己的實際項目工作中。這篇文章的作者來自yahoo的異常表現小組。他們是一個很小的隊伍,專門針對雅虎的產品進行品質檢測和改進,該作者作為 一個後端工程師,現在卻開始搗鼓前端代碼最佳化方面的工程,他認為這是一個極好的進步的機會。他的目標是改進使用者端體驗,他度量了在各個頻寬下瀏覽器的響應 時間,得出如下的一個圖表,它展示了來自http://yahoo.com/的http的流量。現在我們來好好學習一下:
以標的第一個標籤就是html,是一個html文檔最開始載入的東東,在這個例子中,讀取html代碼只佔了整個回應時間中的5%,這個結果適 用於絕大多數網站,在採樣美國的前十位網站中,只有一家超過5%但少於20%,其餘80%的時間是用來讀取網頁其他內容的,也就是說,前端(原文是 front-end,意思就是不包括html代碼的其餘內容,可以是圖片,指令碼,flash,視頻,各種東西)。這就是為什麼我們要把目光集中在這些東西 來提高顯示速度的關鍵原因。
為什麼要從前端開始著手有三個主要原因:
這裡有提升和改進的潛力。如果能減少一半的體積,就能減少40%的回應時間。
改進前端比改進後端需要的時間和資源更少。(改進後端要重新設計應用程式規劃,代碼,尋找最佳化代碼的方法,添加或改變硬體設定,分散式資料庫,等等)
前端的改進在我們的工作中已經被證實,我們在yahoo有五十個小組,在我們的最佳表現規則下,提高了他們的使用者端回應時間達到25%或更高。
我們的黃金規則是:首先最佳化前端表現,這些東西耗費了使用者端回應時間中的80%。
1.減少http請求數
圖片,css,script,flash,等等這些都會增加http請求數,減少這些元素的數量能減少回應時間。
CSS Sprites技術能減少圖片的請求數,把零散的小圖片放到一起,運用background-position來改變背景圖片的位置,前提是html元素事先定義好寬高,其實就像一個遮罩,移動背景就會看到不同的景象。
內嵌映像 用data:URL scheme的方式把圖片內容代碼直接嵌入html代碼中,這樣會增大html代碼的體積,改進的方式是把內嵌圖片嵌入到css中(css被緩衝),這樣就會更好的減少http請求數而且不增大html的體積。
很多使用者都是在空緩衝的情況下進入你的網站的,這樣第一次的速度就會顯得很重要。
第一條規則是最重要的一條規則。
2.運用cdn技術
具體方式,可以Google一下。
3.加一個長時間到期的頭部
Expires: Thu, 15 Apr 2010 20:00:00 GMT
瀏覽器會用緩衝來減少http請求數來加快頁面載入的時間,如果頁面頭部加一個很長的到期時間,瀏覽器就會一直快取頁面面裡的元素。
不過這樣會帶來一個問題,就是如果頁面裡的東西變動的話就要改名字了,否則使用者端不會主動重新整理,在yahoo工作群組用的是版本號碼,例如yahoo_2.0.6.js
4.Gzip壓縮
Gzip是現在最流行和最有效壓縮方式,她是GNU開發的,RFC1952標準化。
(Gzip是在伺服器端壓縮圖片,css,指令碼等,傳送到使用者端的瀏覽器再解壓,這樣可以提高傳輸速度,不過對伺服器的壓力會增大,一般選擇部分元素壓縮比較合適。)
5.把樣式表放到頂部
我們發現把css放到文檔頭部會讓網頁載入得更快。因為這樣可以讓頁面逐漸載入。
把樣式表放到接近底部的問題是它阻止了頁面元素的逐漸顯示。這樣還會導致“flash of unstyled content” 即在樣式表載入之前頁面內容是以沒有樣式的形式顯示出來的,待載入完樣式後,頁面重繪,內容一閃即改變了樣式表現。
6.把指令碼放到底部
把指令碼放到儘可能底部的地方,一個原因是讓頁面逐漸渲染,另一個是實現更好的並行下載。
對於指令碼,指令碼以下的內容被阻止逐漸載入了,因為只有當下載完指令碼以後才會下載下面的內容,第二個指令碼引起的問題是阻止平行下載。 “http/1.1 specification”建議瀏覽器對一個網域名稱, 同一時間下載數不超過2個(按:實際監測發現一般有超過2個),我曾經讓ie並行下載100個圖片。 當指令碼正在下載的時候,瀏覽器不會開始下載任何東西。
7.避免css expressions
css expressions 是一個有力(和危險)的方式動態改變css的屬性。他們自ie5就開始被支援,舉個例子,用css expression可以讓背景色每個小時輪換一次。但是被非ie瀏覽器忽略的。
background-color: expression( (new Date()).getHours()%2 ? “#B8D4FF” : “#F08A00″ );
expressions的問題就在與它的計算頻率絕對超出我們的想象,甚至當我們移動滑鼠,都會引起頁面的重繪!
下面是舉例頁面
減少css expressions計算次數的一個方法就是使用一次性的expressions。 當第一次expression計算出一個明確的值,就讓樣式等於這個值,不再變動。如果樣式的屬性一定要動態改變,就用時間控制代碼吧!
8.讓指令碼和樣式外延
Javascript和CSS應該是外部調用還是內嵌呢?
用外部調用檔案的方式更快,因為他們是可以被緩衝的,如果是內嵌在頁面中他們就無法被緩衝了!想想如果使用者要在你的網站看很多很多的頁面,如果都是使用同一個外部指令碼和樣式,那麼他們一旦被緩衝,就再也不需要下載了,這樣會給你帶來很大的潛在好處。
9.減少DNS查詢
10.減小指令碼體積
有兩個比較流行的工具是用來減小指令碼的體積的–JSMin和YUI Compressor。(按:這個壓縮和Gzip壓縮是不一樣的,Gzip是傳輸壓縮,這個是代碼壓縮)
11.避免重新導向
重新導向會減慢使用者體驗,它會延遲所有的東西直至到達新頁面。一個最浪費的重新導向經常會發生而我們的開發人員又會經常忽略的就是比如 http://astrology.yahoo.com/astrology的結果是重新導向到http://astrology.yahoo.com /astrology/ 在Apache裡用Alias 或者mod_rewrite或者DirectorySlash解決。
從一箇舊網站跳轉到新網站也是經常要用到重新導向,還有就是串連一個網站中的不同部分和在某些情況下(比如不同瀏覽器,不同的使用者帳號類型,等等)的使用者導 向。用重新導向很簡單,而且只需要一點額外的代碼,雖然在這些情況下用重新導向減少了開發人員的複雜度,但它降低了使用者的體驗,變通的做法是用Alias和 mod_rewrite如果兩個部分是在同一主機上的話,如果是由網域名稱變更引起的重新導向,變通的做法是通過Alias或mod_rewrite建立一個 CNAME(一個DNS記錄,建立一個別名,從一個網域名稱指向另一個網域名稱)
12.去掉重複的指令碼
(按:簡單的說,同一個指令碼如果被調用多次,瀏覽器並不會忽略後續的指令碼,而總是覆蓋載入,覆蓋運行,這樣會增加開銷)
13.配置ETags
ETags(Entity tags)是伺服器和瀏覽器的一個功能,它用來判斷瀏覽器緩衝裡的元素是否和原來伺服器上的一致。ETags比last-modified date更具有彈性,它用一個獨一無二的字串來標識一個元素的版本。
原始伺服器用回應標頭裡的ETag來特定一個元素的ETag:
HTTP/1.1 200 OK
Last-Modified: Tue, 12 Dec 2006 03:03:59 GMT
ETag: “10c24bc-4ab-457e1c1f”
Content-Length: 12195
之後,如果瀏覽器要驗證這個元素,它就會用If-None-Match頭來回傳ETag到原始伺服器。如果符合的話,一個304狀態的代碼就會從原始伺服器返回到瀏覽器,這樣原始伺服器就節省了傳輸具體資料的開銷。
GET /i/yahoo.gif HTTP/1.1
Host: us.yimg.com
If-Modified-Since: Tue, 12 Dec 2006 03:03:59 GMT
If-None-Match: “10c24bc-4ab-457e1c1f”
HTTP/1.1 304 Not Modified
用Etags的問題就在於它會標識那個特定的伺服器,如果換了伺服器,Etags也就失去了原有的功能,但是這種現在在網路上太常見了,因為我們經常用伺服器叢集。預設情況下,Apache和IIS會在Etag中內嵌資料,這樣會動態減少驗證成功的機會。
Apache1.3和2.x的ETag格式是inode-size-timestamp。雖然一個檔案可能在不同伺服器的同一個目錄,同樣的大小,安全級,時間戳記等等,它的inode會隨著伺服器的不同而不同。
IIS5.0和6.0有同樣類似Etags的東西,叫時間戳記:ChangeNumber(更改號),更改號是一個用來追蹤IIS配置變化的計數器,ChangeNumber在不同IIS伺服器之間是不一樣的。
它最終的問題就是,IIS和Apache產生的Etags會在不同伺服器之間無法匹配,這樣我們的瀏覽器就無法得到我們期待的304響應,而給我們 的是一個普通的200響應,和正常的資料流。如果你的網站只有一個伺服器還無所謂,如果是叢集,而你用的是預設的ETag配置,你的使用者就會獲得更慢的頁 面,你的伺服器也會有更高的負載,消耗更大的頻寬資源,代理也無法高效緩衝你的內容,甚至即使你有一個長時間到期的頭部(按:見第三條規則),也不會阻止 它重新載入內容。
如果你不想發揮Etags提供的這個彈性驗證模型的優勢,你最好關掉它。Apache中關掉它的方法是在Apache的設定檔中寫這麼一句:
FileETag none
14.讓Ajax緩衝
人們會問這些規則同樣適用於web2.0嗎?當然!這個規則是我在雅虎工作做web2.0後得出的第一條規則。
Ajax的一個好處是它會給你即時的回饋,因為它和背景伺服器是非同步傳輸的,然而,用Ajax並不能保證你的使用者不用無聊的撥弄手指頭來等待這個 回饋,在很多應用中,使用者是否需要等待取決於Ajax是怎麼用的,舉例說,在一個基於網頁的郵件用戶端,使用者會持續等待Ajax的回饋來搜尋符合他的標準 的郵件資訊。記住“非同步”並不意味著“即時”。讓它緩衝的方式同樣是加一個到期頭部。
由於不錯,轉載與:雲南SEO最佳化 雲南網站建設