上個月,Yahoo!優異性能(Yahoo!'s Exceptional Performance)開發團隊成員 Stoyan Stefanov 出席了蒙特利爾的2008魁北克PHP會議演講。他提供了他們團隊最新的研究成果和提高網頁性能規則20條。在早先的高性能網頁開發14條軍規已經讓大家耳熟能詳,此次新增的20條更加全面,覆蓋了伺服器端、cookies、頁面內容、JavaScript、CSS、圖片、移動手機應用這七大類別。以下內容就是根據這二十條結合個人在實際開發中的理解所做的全面解讀。希望對大家開發有所助益。
閱讀指導:
1. 每條規則後會指明是針對上述所說的七大類別中哪個類別的優化。
2. 文中提到的一些工具在文後附注中會提供簡要說明。
3. 文中經常提到“元件”這個詞,這個詞不同于我們程式開發中常提到的元件概念。本文中提到的“組件”特指嵌在HTML頁面中圖片、JavaScript腳本、CSS等靜態檔。
一、儘早清除緩衝區[伺服器端]
假如使用者請求一個頁面,而這個頁面在後端伺服器需要花200至500毫秒乃至更長時間才能生成最終HTML頁面,這時候使用者流覽器處於較長時間的、等待頁面資料返回的空閒狀態,使用者體驗不會很好。此時可以根據頁面內容長短做適當分隔,將先生成的頁面局部HTML緩衝內容提前發送到用戶端,不必讓伺服器消耗記憶體緩衝完整個龐大的頁面內容後再行輸出。這種方法有益於處理後端負荷大而前端負荷輕的頁面。
在HTML頁面的head標籤位置後是清除緩衝的好位置,因為HTML的head標籤可以包括 CSS 和 JavaScript 檔,對於流覽器而言獲取頁面顯示與後端伺服器處理並行的效果較好。在PHP中有一個函數 flush(),它可以發送請求頁面的局部HTML代碼給流覽器,以便流覽器能先取得頁面已經生成的部分HTML,同時後端伺服器繼續忙於處理生成頁面餘下的HTML。以下以此函數做個示例:view plaincopy to clipboardprint?
...
...
...
...
其他語言也有類似語法,如ASP.NET和ASP中的 Response.Flush()。
注意:在實際Web開發中,儘量減少HTTP請求次數是優化的重要方面,這條基本原則是早先14條和新增20條中很多規則的制訂基礎,實際上它也是14條規則中第一條也是非常重要的一條規則,但是使用儘早清除緩衝語句會增加一個頁面的HTTP請求次數,這無疑是一個矛盾,因此請注意本條規則的適用範圍,不要濫用它。
二、使用GET方法的AJAX請求[伺服器端]
這個容易理解一些。AJAX經常要用XMLHttpRequest,但是它的POST方法在流覽器中完成需要執行兩步:首先發送資訊頭,然後才是發送資料;而GET方法只用一個TCP資料包傳遞(cookies資訊例外)即可,減少了一個步驟,速度會快些。
另外根據HTTP規範,GET方法就是為獲取資訊而生的。因此僅在請求資料而不是發送資料給伺服器端存儲時,使用GET方法很有意義。
要注意的是,IE中URL允許最大允許長度是2K,用GET方法發送資料時注意2K的這個限制。
三、後載入元件[頁面內容]
使用該方法的意義在於:如果某個頁面內容豐富多彩的話,在流覽器載入顯示它時速度就不會很快。使用後載入元件的方法可以通過延遲載入一些隱藏內容來保證流覽器優先顯示初始頁面。
要做到這一點必須仔細觀察自己的頁面並且問自己:“解釋生成一個完整頁面,什麼部分內容是開始載入時絕對必須顯示的?”清楚了這個問題,那麼那些餘下內容和元件就可以採用後載入方法延遲生成。這樣會大大加快頁面顯示速度。
這個技巧通常是JavaScript通過處理頁面載入時的onload事件完成。例如,使用JavaScript代碼和庫去執行拖放動態效果操作時,這些操作可以延遲,因為拖動頁面上元素的操作只能等初始頁面生成完後才能發生。頁面中的隱藏內容也適合用後載入方式,因為只有頁面載入完畢使用者才能操作決定是否顯示該內容。
Yahoo!網站的首頁內容繁多,觀察處於隱藏狀態下的內容,這些內容通常在一些選項卡一樣的標籤頁當中,只有點擊後才會載入。
只要明白該規則的優化要點後相信大家可以通過JavaScript做出自己的具體實現。Yahoo!提供了兩個用於實現後載入方法的工具:
◆ YUI Image Loader:可以延遲圖片顯示
◆ YUI Get utility:它可以在頁面載入完成後把JavaScript和CSS資源綁定到DOM上去。
以上的工具是Yahoo!的YUI庫提供。
四、預載入元件[頁面內容]
從文字上看預載入元件與後載入元件似乎作用相反,但實際上二者目標是完全不同的。通過預先載入元件可以充分利用流覽器的閒置時間,並且可以請求未來頁面需要的元件。在這種情況下,當使用者訪問下一個頁面時,你已經提前讓大多數元件保存在緩存中,使用者載入這個頁面就會非常快。
預載入類型有下列三種:
1. 無條件預載入
onload事件一觸發,就要馬上取回一些指定的組件。可以檢查google.com首頁中onload事件中請求Sprite圖片的例子(注:什麼是Sprite圖片,請參看第十六條規則)。在這個例子可以看出這個sprite圖片:
在google.com首頁本身並不需要, 但它會在隨後使用者搜索生成的結果頁面中需要。
2. 條件預載入
根據使用者操作預測使用者下一步操作的方向,並據此做預載入。例如,search.yahoo.com中,在輸入框中剛鍵入幾個字元後,就會看到頁面對你鍵入的詞做出合理推測,推出幾個可能要搜索的實際關鍵字。此方法目前穀歌(google.cn)也在使用。
3. 提前預載入
在將重新設計的網站頁面發佈前用此法較好。頁面重新設計後常會有這樣的回饋:“新網站太酷了,就是比以前慢”。原因在於用戶訪問舊網站是全緩存的,但新網站還沒有緩存過。這時可以在發佈新設計前就預載入一些新網站元件,這可以減少沒有緩存的副作用。可以利用用戶訪問舊網站時流覽器空閒的時間請求新網站要使用的圖片、腳本等。
五、減少 DOM 元素數量[頁面內容]
一個複雜的頁面意味著要請求下載的位元組數更多,也意味著用JavaScript訪問DOM速度更慢。
如何儘量減少已有頁面的 DOM 元素數量呢?一個重要的思路就是不要濫用表格table和div 。很多人習慣用一些網頁編輯軟體去設計頁面,這樣會導致大量嵌套的表格或在使用語義不合法的標記。使用div要僅當它在語義上有意義時才使用它,有些開發者使用它僅僅是因為它可以被流覽器解釋生成一個新行。
Yahoo! 提供了一個避免這些問題的方法——使用YUI CSS工具。grids.css 有助於整體佈局設計,fonts.css 和 reset.css 有且於清除流覽器的默認格式設置。這些工具可以在Yahoo!的YUI頁面中去找。
DOM元素的數量可在Firebug的Console上鍵入 document.getElementsByTagName('*').length 得到。
DOM 元素不超過多少才適當呢?這可以通過檢查一些有良好設計的頁面來感覺比較。如Yahoo! 主頁訪問量相當大,它的數量在700個元素(HTML標籤)以下。
六、分隔元件到多個域中[頁面內容]
對終端使用者回應時間影響最大的就是所請求頁面所含元件數量。只要流覽器緩存為空,下載每個元件需要佔用額外的HTTP請求,只有緩存滿時才可能不佔用。
HTTP/1.1規範中建議流覽器對每一個主機名稱允許併發下載兩個元件。預設狀態下,Internet Explorer和Firefox都符合這個規範。注意:IE8.0默認允許6個併發請求。
許多網頁中所有元件都從同一主機名稱中下載,這時不僅回應時間受併發執行緒數限制,同時也受該伺服器CPU和頻寬限制。把頁面元件分佈在兩個主機名稱中,整體回應時間就會快2倍,CPU和頻寬消耗也會得以分擔。
七、儘量減少 HTML 標籤 iframe 的使用數[頁面內容]
iframe允許在父文檔內插入一個HTML文檔。要想高效使用iframes,理解它的工作方式很重要。
使用iframe有如下好處:
◆ 有助於減慢顯示協力廠商標記和廣告內容。
◆ 是個安全的 Sandbox。
◆ 能併發下載腳本。
但同時也有弊端:
◆ 即使iframe 內的 HTML 文檔內容為空,消耗也比較高。
◆ 會阻止頁面的onload事件
◆ 非語義的
八、避免404頁面[頁面內容]
如果做了一個HTTP請求然後得到一個無用的回應頁面,不僅完全不必要而且會降低用戶體驗。404頁面就是在沒有發現指定資源時返回的頁面。
一些網站提供了有益的404提示,對用戶體驗有好處,但這畢竟浪費了伺服器資源。當連結一個外部JavaScript檔,而它又出了404錯誤,這尤其糟糕。首先,因為這個下載有問題會阻止併發下載;其次,即使有錯流覽器仍然會盡力解析404返回的內容,看看有無JavaScript代碼,盡力查找裡面可用代碼。
沒有留言:
發佈留言