高性能web開發軍規

上個月,Yahoo!優異性能(Yahoo!'s Exceptional Performance)開發團隊成員 Stoyan Stefanov 出席了蒙特利爾的2008魁北克PHP會議演講。他提供了他們團隊最新的研究成果和提升網頁性能規則20條。在早先的高性能網頁開發14條軍規已經讓你們耳熟能詳,這次新增的20條更加全面,覆蓋了服務器端、cookies、頁面內容、JavaScript、CSS、圖片、移動手機應用這七大類別。如下內容就是根據這二十條結合我的在實際開發中的理解所作的全面解讀。但願對你們開發有所助益。


閱讀指導:

1. 每條規則後會指明是針對上述所說的七大類別中哪一個類別的優化。

2. 文中提到的一些工具在文後附註中會提供簡要說明。

3. 文中常常提到「組件」這個詞,這個詞不一樣於咱們程序開發中常提到的組件概念。本文中提到的「組件」特指嵌在HTML頁面中圖片、JavaScript腳本、CSS等靜態文件。

1、儘早清除緩衝區[服務器端]

   假如用戶請求一個頁面,而這個頁面在後端服務器須要花200至500毫秒乃至更長時間才能生成最終HTML頁面,這時候用戶瀏覽器處於較長時間的、等待頁面數據返回的空閒狀態,用戶體驗不會很好。此時能夠根據頁面內容長短作適當分隔,將先生成的頁面局部HTML緩衝內容提早發送到客戶端,沒必要讓服務器消耗內存緩衝完整個龐大的頁面內容後再行輸出。這種方法有益於處理後端負荷大而前端負荷輕的頁面。

   在HTML頁面的head標籤位置後是清除緩衝的好位置,由於HTML的head標籤能夠包括 CSS 和 JavaScript 文件,對於瀏覽器而言獲取頁面顯示與後端服務器處理並行的效果較好。在PHP中有一個函數 flush(),它能夠發送請求頁面的局部HTML代碼給瀏覽器,以便瀏覽器能先取得頁面已經生成的部分HTML,同時後端服務器繼續忙於處理生成頁面餘下的HTML。如下以此函數作個示例:php

.. <!-- css, js -->

</head>

<!-- 注意此處flush()是放在了head標籤位置後面 -->

<?php flush(); ?>

<body>

... <!-- content -->




   其餘語言也有相似語法,如ASP.NET和ASP中的 Response.Flush()。

   注意:在實際Web開發中,儘可能減小HTTP請求次數是優化的重要方面,這條基本原則是早先14條和新增20條中不少規則的制訂基礎,實際上它也是14條規則中第一條也是很是重要的一條規則,可是使用盡早清除緩衝語句會增長一個頁面的HTTP請求次數,這無疑是一個矛盾,所以請注意本條規則的適用範圍,不要濫用它。

2、使用GET方法的AJAX請求[服務器端]

   這個容易理解一些。AJAX常常要用XMLHttpRequest,可是它的POST方法在瀏覽器中完成須要執行兩步:首先發送信息頭,而後纔是發送數據;而GET方法只用一個TCP數據包傳遞(cookies信息例外)便可,減小了一個步驟,速度會快些。

   另外根據HTTP規範,GET方法就是爲獲取信息而生的。所以僅在請求數據而不是發送數據給服務器端存儲時,使用GET方法頗有意義。

   要注意的是,IE中URL容許最大容許長度是2K,用GET方法發送數據時注意2K的這個限制。

3、後加載組件[頁面內容]

   使用該方法的意義在於:若是某個頁面內容豐富多彩的話,在瀏覽器加載顯示它時速度就不會很快。使用後加載組件的方法能夠經過延遲加載一些隱藏內容來保證瀏覽器優先顯示初始頁面。css

要作到這一點必須仔細觀察本身的頁面而且問本身:「解釋生成一個完整頁面,什麼部份內容是開始加載時絕對必須顯示的?」清楚了這個問題,那麼那些餘下內容和組件就能夠採用後加載方法延遲生成。這樣會大大加快頁面顯示速度。

   這個技巧一般是JavaScript經過處理頁面加載時的onload事件完成。例如,使用JavaScript代碼和庫去執行拖放動態效果操做時,這些操做能夠延遲,由於拖動頁面上元素的操做只能等初始頁面生成完後才能發生。頁面中的隱藏內容也適合用後加載方式,由於只有頁面加載完畢用戶才能操做決定是否顯示該內容。

   Yahoo!網站的首頁內容繁多,觀察處於隱藏狀態下的內容,這些內容一般在一些選項卡同樣的標籤頁當中,只有點擊後纔會加載。

   只要明白該規則的優化要點後相信你們能夠經過JavaScript作出本身的具體實現。Yahoo!提供了兩個用於實現後加載方法的工具:

◆ YUI Image Loader:能夠延遲圖片顯示

◆ YUI Get utility:它能夠在頁面加載完成後把JavaScript和CSS資源綁定到DOM上去。

   以上的工具是Yahoo!的YUI庫提供。

4、預加載組件[頁面內容]

   從文字上看預加載組件與後加載組件彷佛做用相反,但實際上兩者目標是徹底不一樣的。經過預先加載組件能夠充分利用瀏覽器的空閒時間,而且能夠請求將來頁面須要的組件。在這種狀況下,當用戶訪問下一個頁面時,你已經提早讓大多數組件保存在緩存中,用戶加載這個頁面就會很是快。

   預加載類型有下列三種:




1. 無條件預加載

   onload事件一觸發,就要立刻取回一些指定的組件。能夠檢查google.com首頁中 Sprite圖片,請參看第十六條規則)。在這個例子能夠看出這個sprite圖片www.google.com/p_w_picpaths /nav_logo3.png在google.com首頁自己並不須要, 但它會在隨後用戶搜索生成的結果頁面中須要。

2. 條件預加載

   根據用戶操做預測用戶下一步操做的方向,並據此作預加載。例如,search.yahoo.com中,在輸入框中剛鍵入幾個字符後,就會看到頁面對你鍵入的詞作出合理推測,推出幾個可能要搜索的實際關鍵詞。此方法目前谷歌(google.cn)也在使用。



3. 提早預加載

   在將從新設計的網站頁面發佈前用此法較好。頁面從新設計後常會有這樣的反饋:「新站點太酷了,就是比之前慢」。緣由在於用戶訪問舊站點是全緩存的,但新站點尚未緩存過。這時能夠在發佈新設計前就預加載一些新站點組件,這能夠減小沒有緩存的反作用。能夠利用用戶訪問舊站點時瀏覽器空閒的時間請求新站點要使用的圖片、腳本等。

5、減小 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標籤)如下。

6、分隔組件到多個域中[頁面內容]

   對終端用戶響應時間影響最大的就是所請求頁面所含組件數量。只要瀏覽器緩存爲空,下載每一個組件須要佔用額外的HTTP請求,只有緩存滿時纔可能不佔用。前端

HTTP/1.1規範中建議瀏覽器對每個主機名容許併發下載兩個組件。默認狀態下,Internet Explorer和Firefox都符合這個規範。注意:IE8.0默認容許6個併發請求。

   許多網頁中全部組件都從同一主機名中下載,這時不只響應時間受併發線程數限制,同時也受該服務器CPU和帶寬限制。把頁面組件分佈在兩個主機名中,總體響應時間就會快2倍,CPU和帶寬消耗也會得以分擔。

7、儘可能減小 HTML 標籤 iframe 的使用數[頁面內容]

   iframe容許在父文檔內插入一個HTML文檔。要想高效使用iframes,理解它的工做方式很重要。

   使用iframe有以下好處:

◆ 有助於減慢顯示第三方標記和廣告內容。

◆ 是個安全的 Sandbox。

◆ 能併發下載腳本。

但同時也有弊端:

◆ 即便iframe 內的 HTML 文檔內容爲空,消耗也比較高。

◆ 會阻止頁面的onload事件

◆ 非語義的

8、避免404頁面[頁面內容]

   若是作了一個HTTP請求而後獲得一個無用的響應頁面,不只徹底沒必要要並且會下降用戶體驗。404頁面就是在沒有發現指定資源時返回的頁面。後端

相關文章
相關標籤/搜索