新聞資訊

[轉載]雅虎35條優化黃金守則(一(yī / yì /yí))

Yahoo!的(de) Exceptional Performance團隊爲(wéi / wèi)改善 Web性能帶來(lái)最佳實踐。他(tā)們爲(wéi / wèi)此進行了(le/liǎo)一(yī / yì /yí)系列的(de)實驗、開發了(le/liǎo)各種工具、寫了(le/liǎo)大(dà)量的(de)文章和(hé / huò)博客并在(zài)各種會議上(shàng)參與探讨。最佳實踐的(de)核心就(jiù)是(shì)旨在(zài)提高網站性能。總結出(chū)了(le/liǎo)一(yī / yì /yí)系列可以(yǐ)提高網站速度的(de)方法。可以(yǐ)分爲(wéi / wèi) 7大(dà)類 35條。包括内容 、服務器 、 CSS 、 JavaScript 、Cookie 、圖片 、移動應用 ,七部分。

一(yī / yì /yí)、内容部分

  • 盡量減少 HTTP請求
  • 減少 DNS查找
  • 避免跳轉
  • 緩存 Ajxa
  • 推遲加載
  • 提前加載
  • 減少 DOM元素數量
  • 用域名劃分頁面内容
  • 使 frame數量最少
  • 避免 404錯誤

1、盡量減少 HTTP請求次數

       終端用戶響應的(de)時(shí)間中,有 80%用于(yú)下載各項内容。這(zhè)部分時(shí)間包括下載頁面中的(de)圖像、樣式表、腳本、 Flash等。通過減少頁面中的(de)元素可以(yǐ)減少 HTTP請求的(de)次數。這(zhè)是(shì)提高網頁速度的(de)關鍵步驟。

  減少頁面組件的(de)方法其實就(jiù)是(shì)簡化頁面設計。那麽有沒有一(yī / yì /yí)種方法既能保持頁面内容的(de)豐富性又能達到(dào)加快響應時(shí)間的(de)目的(de)呢?這(zhè)裏有幾條減少HTTP請求次數同時(shí)又可能保持頁面内容豐富的(de)技術。


合并文件是(shì)通過把所有的(de)腳本放到(dào)一(yī / yì /yí)個(gè)文件中來(lái)減少 HTTP請求的(de)方法,如可以(yǐ)簡單地(dì / de)把所有的(de) CSS文件都放入一(yī / yì /yí)個(gè)樣式表中。當腳本或者樣式表在(zài)不(bù)同頁面中使用時(shí)需要(yào / yāo)做不(bù)同的(de)修 改,這(zhè)可能會相對麻煩點,但即便如此也(yě)要(yào / yāo)把這(zhè)個(gè)方法作爲(wéi / wèi)改善頁面性能的(de)重要(yào / yāo)一(yī / yì /yí)步。

CSS Sprites是(shì)減少圖像請求的(de)有效方法。把所有的(de)背景圖像都放到(dào)一(yī / yì /yí)個(gè)圖片文件中,然後通過 CSS的(de) background-image和(hé / huò) background-position屬性來(lái)顯示圖片的(de)不(bù)同部分;


圖片地(dì / de)圖是(shì)把多張圖片整合到(dào)一(yī / yì /yí)張圖片中。雖然文件的(de)總體大(dà)小不(bù)會改變,但是(shì)可 以(yǐ)減少 HTTP請求次數。圖片地(dì / de)圖隻有在(zài)圖片的(de)所有組成部分在(zài)頁面中是(shì)緊挨在(zài)一(yī / yì /yí)起的(de)時(shí)候才能 使用,如導航欄。确定圖片的(de)坐标和(hé / huò)可能會比較繁瑣且容易出(chū)錯,同時(shí)使用圖片地(dì / de)圖導航也(yě)不(bù)具有可讀性,因此不(bù)推薦這(zhè)種方法;


内聯圖像是(shì)使用 data:URL scheme的(de)方法把圖像數據加載頁面中。這(zhè)可能會增加頁面的(de)大(dà) 小。把内聯圖像放到(dào)樣式表(可緩存)中可以(yǐ)減少 HTTP請求同時(shí)又避免增加頁面文件的(de)大(dà)小。但是(shì)内聯圖像現在(zài)還沒有得到(dào)主流浏覽器的(de) 支持。


  減少頁面的(de) HTTP請求次數是(shì)你首先要(yào / yāo)做的(de)一(yī / yì /yí)步。這(zhè)是(shì)改進首次訪問用戶等待時(shí)間的(de)最重要(yào / yāo)的(de)方法。 如同 Tenni Theurer的(de)他(tā)的(de)博客 Browser Cahe Usage - Exposed!中所說(shuō), HTTP請求在(zài)無緩存情況下占去了(le/liǎo) 40%到(dào) 60%的(de)響應時(shí)間。讓那些初次訪問你網站的(de)人(rén)獲得更加快速的(de)體驗吧!


2、減少 DNS查找次數

  域名系統( DNS)提供了(le/liǎo)域名和(hé / huò) IP的(de)對應關系,就(jiù)像電話本中人(rén)名和(hé / huò)他(tā)們的(de)電話号碼的(de)關系一(yī / yì /yí)樣。當你在(zài)浏覽器地(dì / de)址欄中 輸入 www.yahoo.com 時(shí), DNS解析服務器就(jiù)會返回這(zhè)個(gè)域名對應的(de) IP地(dì / de)址。 DNS解析的(de)過程同樣也(yě)是(shì)需要(yào / yāo)時(shí)間的(de)。一(yī / yì /yí)般情況下返回給定域名對應的(de) IP地(dì / de)址會花費 20到(dào) 120毫秒的(de)時(shí)間。而(ér)且在(zài)這(zhè)個(gè)過程中浏覽器什麽都不(bù)會做直到(dào) DNS查找完畢。


   緩存 DNS查找可以(yǐ)改善頁面性能。這(zhè)種緩存需要(yào / yāo)一(yī / yì /yí)個(gè)特定的(de)緩存服務器,這(zhè)種服務器一(yī / yì /yí)般屬于(yú)用戶的(de) ISP提供商或者本地(dì / de)局域網控制,但是(shì)它同樣會在(zài)用戶使用的(de)計算機上(shàng)産生緩存。 DNS信息會保留在(zài)操作系統的(de) DNS緩存中(微軟 Windows系統中 DNS Client Service)。大(dà)多數浏覽器有獨立于(yú)操作系統以(yǐ)外的(de)自己的(de)緩存。由于(yú)浏覽器有自己的(de)緩存記錄,因此在(zài)一(yī / yì /yí)次請求中它不(bù)會受到(dào)操作系統的(de)影響。


  Internet Explorer 默認情況下對 DNS查找記錄的(de)緩存時(shí)間爲(wéi / wèi) 30分鍾,它在(zài)注冊表中的(de)鍵值爲(wéi / wèi) DnsCacheTimeout。 Firefox對 DNS的(de)查找記錄緩存時(shí)間爲(wéi / wèi) 1分鍾,它在(zài)配置文件中的(de)選項爲(wéi / wèi) network.dnsCacheExpiration( Fasterfox把這(zhè)個(gè)選項改爲(wéi / wèi)了(le/liǎo) 1小時(shí))。


  當客戶端中的(de) DNS緩存都爲(wéi / wèi)空時(shí)(浏覽器和(hé / huò)操作系統都爲(wéi / wèi)空), DNS查找的(de)次數和(hé / huò)頁面中主機名的(de)數量相同。這(zhè)其中包括頁面中 URL、圖片、腳本文件、樣式表、Flash對象等包含的(de)主機名。減少主機名的(de)數量可以(yǐ)減少DNS查找次數。


  減少主機名的(de)數量還可以(yǐ)減少頁面中并行下載的(de)數量。減少 DNS查找次數可以(yǐ)節省響應時(shí)間,但是(shì)減少并行下載卻會增加響應時(shí)間。我的(de)指導原則是(shì) 把這(zhè)些頁面中的(de)内容分割成至少兩部分但不(bù)超過四部分。這(zhè)種結果就(jiù)是(shì)在(zài)減少 DNS查找次數和(hé / huò)保持較高程度并行下載兩者之(zhī)間的(de)權衡了(le/liǎo)。


3、避免跳轉

跳轉是(shì)使用 301和(hé / huò) 302代碼實現的(de)。下面是(shì)一(yī / yì /yí)個(gè)響應代碼爲(wéi / wèi) 301的(de) HTTP頭:

      HTTP/1.1 301 Moved Permanently

      Location: http://example.com/newuri

      Content-Type: text/html

  浏覽器會把用戶指向到(dào) Location中指定的(de) URL。頭文件中的(de)所有信息在(zài)一(yī / yì /yí)次跳轉中都是(shì)必需的(de),内容部分可以(yǐ)爲(wéi / wèi)空。不(bù)管他(tā)們的(de)名 稱, 301和(hé / huò) 302響應都不(bù)會被緩存除非增加一(yī / yì /yí)個(gè)額外的(de)頭選項,如 Expires或者 Cache-Control來(lái)指定它緩存。 <meat />元素的(de)刷新标簽和(hé / huò)JavaScript也(yě)可以(yǐ)實現 URL的(de)跳轉,但是(shì)如果你必須要(yào / yāo)跳轉的(de)時(shí)候,最好的(de)方法就(jiù)是(shì)使用标準的(de) 3XXHTTP狀态代碼,這(zhè)主要(yào / yāo)是(shì)爲(wéi / wèi)了(le/liǎo)确保“後退”按鈕可以(yǐ)正确地(dì / de)使用。


  但是(shì)要(yào / yāo)記住跳轉會降低用戶體驗。在(zài)用戶和(hé / huò) HTML文檔中間增加一(yī / yì /yí)個(gè)跳轉,會拖延頁面中所有元素的(de)顯示,因爲(wéi / wèi)在(zài) HTML文件被加載前任何文件(圖像、 Flash等)都不(bù)會被下載。


  有一(yī / yì /yí)種經常被網頁開發者忽略卻往往十分浪費響應時(shí)間的(de)跳轉現象。 這(zhè)種現象發生在(zài)當 URL本該有斜杠( /)卻被忽略掉時(shí)。例如,當我們要(yào / yāo)訪問http://astrology.yahoo.com/astrology 時(shí),實際上(shàng)返回的(de)是(shì)一(yī / yì /yí)個(gè)包含 301代碼的(de)跳轉,它指向的(de)是(shì) http://astrology.yahoo.com/astrology/  (注意末尾的(de)斜杠)。在(zài) Apache服務器中可以(yǐ)使用 Alias 或者 mod_rewrite或者 the DirectorySlash來(lái)避免。


  連接新網站和(hé / huò)舊網站是(shì)跳轉功能經常被用到(dào)的(de)另一(yī / yì /yí)種情況。這(zhè)種情況 下往往要(yào / yāo)連接網站的(de)不(bù)同内容然後根據用戶的(de)不(bù)同類型(如浏覽器類型、用戶賬号所屬類型)來(lái)進行跳轉。使用跳轉來(lái)實現兩個(gè)網站的(de)切換十分簡單,需要(yào / yāo)的(de)代碼量 也(yě)不(bù)多。盡管使用這(zhè)種方法對于(yú)開發者來(lái)說(shuō)可以(yǐ)降低複雜程度,但是(shì)它同樣降低用戶體驗。一(yī / yì /yí)個(gè)可替代方法就(jiù)是(shì)如果兩者在(zài)同一(yī / yì /yí)台服務器上(shàng)時(shí)使用 Alias和(hé / huò) mod_rewrite和(hé / huò)實現。如果是(shì)因爲(wéi / wèi)域名的(de)不(bù)同而(ér)采用跳轉,那麽可以(yǐ)通過使用 Alias或者 mod_rewirte建立 CNAME(保存一(yī / yì /yí)個(gè)域名和(hé / huò)另外一(yī / yì /yí)個(gè)域名之(zhī)間關系的(de)DNS記錄)來(lái)替代。


4、可緩存的(de) AJAX

  Ajax 經常被提及的(de)一(yī / yì /yí)個(gè)好處就(jiù)是(shì)由于(yú)其從後台服務器傳輸信息 的(de)異步性而(ér)爲(wéi / wèi)用戶帶來(lái)的(de)反饋的(de)即時(shí)性。但是(shì),使用 Ajax并不(bù)能保證用戶不(bù)會在(zài)等待異步的(de) JavaScript和(hé / huò) XML響應上(shàng)花費時(shí)間。在(zài)很多應用中,用戶是(shì)否需要(yào / yāo)等待響應取決于(yú) Ajax如何來(lái)使用。例如,在(zài)一(yī / yì /yí)個(gè)基于(yú) Web的(de) Email客戶端中,用戶必須等待 Ajax返回符合他(tā)們條件的(de)郵件查詢結果。記住一(yī / yì /yí)點,“異步”并不(bù)異味着“即時(shí)”,這(zhè) 很重要(yào / yāo)。


  爲(wéi / wèi)了(le/liǎo)提高性能,優化 Ajax響應是(shì)很重要(yào / yāo)的(de)。提高 Ajxa性能的(de)措施中最重要(yào / yāo)的(de)方法就(jiù)是(shì)使響應具有可緩存性,具體的(de)讨論可以(yǐ)查看 Add an Expires or a Cache-Control Header。 其它的(de)幾條規則也(yě)同樣适用于(yú)Ajax:

    Gizp 壓縮文件

    減少 DNS查找次數

    精簡 JavaScript

    避免跳轉

    配置 ETags


  讓我們來(lái)看一(yī / yì /yí)個(gè)例子(zǐ):一(yī / yì /yí)個(gè) Web2.0的(de) Email客戶端會使用 Ajax來(lái)自動完成對用戶地(dì / de)址薄的(de)下載。如果用戶在(zài)上(shàng)次使用過 Email web應用程序後沒有對地(dì / de)址薄作任何的(de)修改,而(ér)且 Ajax響應通過 Expire或者 Cacke-Control頭來(lái)實現緩存,那麽就(jiù)可以(yǐ)直接從上(shàng)一(yī / yì /yí)次的(de)緩存中讀取地(dì / de)址薄 了(le/liǎo)。必須告知浏覽器是(shì)使用緩存中的(de)地(dì / de)址薄還是(shì)發送一(yī / yì /yí)個(gè)新的(de)請求。這(zhè)可以(yǐ)通過爲(wéi / wèi)讀取地(dì / de)址薄的(de) Ajax URL增加一(yī / yì /yí)個(gè)含有上(shàng)次編輯時(shí)間的(de)時(shí)間戳來(lái)實現,例如, &t=11900241612等。如果地(dì / de)址薄在(zài)上(shàng)次下載後沒有被編輯過,時(shí)間 戳就(jiù)不(bù)變,則從浏覽器的(de)緩存中加載從而(ér)減少了(le/liǎo)一(yī / yì /yí)次 HTTP請求過程。如果用戶修改過地(dì / de)址薄,時(shí)間戳就(jiù)會用來(lái)确定新的(de) URL和(hé / huò)緩存響應并不(bù)匹配,浏覽器就(jiù)會重要(yào / yāo)請求更新地(dì / de)址薄。

  即使你的(de) Ajxa響應是(shì)動态生成的(de),哪怕它隻适用于(yú)一(yī / yì /yí)個(gè)用戶,那麽它也(yě)應該被緩存起來(lái)。這(zhè)樣做 可以(yǐ)使你的(de) Web2.0應用程序更加快捷。


5、推遲加載内容

  你可以(yǐ)仔細看一(yī / yì /yí)下你的(de)網頁,問問自己“哪些内容是(shì)頁面呈現時(shí) 所必需首先加載的(de)?哪些内容和(hé / huò)結構可以(yǐ)稍後再加載?

  把整個(gè)過程按照 onload事件分隔成兩部分, JavaScript是(shì)一(yī / yì /yí)個(gè)理想的(de)選擇。例如,如果你有用于(yú)實現拖放和(hé / huò)動畫的(de) JavaScript,那麽它就(jiù)以(yǐ)等待稍後加載,因爲(wéi / wèi)頁面上(shàng)的(de)拖放元素是(shì)在(zài)初始化呈現 之(zhī)後才發生的(de)。其它的(de)例如隐藏部分的(de)内容(用戶操作之(zhī)後才顯現的(de)内容)和(hé / huò)處于(yú)折疊部分的(de)圖像也(yě)可以(yǐ)推遲加載

  工具可以(yǐ)節省你的(de)工作量: YUI Image Loader可以(yǐ)幫你推遲加載折疊部分的(de)圖片, YUI Get utility是(shì)包含 JS和(hé / huò) CSS的(de)便捷方法。比如你可以(yǐ)打開 Firebug的(de) Net選項卡看一(yī / yì /yí)下 Yahoo的(de)首頁。

  當性能目标和(hé / huò)其它網站開發實踐一(yī / yì /yí)緻時(shí)就(jiù)會相得益彰。這(zhè)種情況 下,通過程序提高網站性能的(de)方法告訴我們,在(zài)支持 JavaScript的(de)情況下,可以(yǐ)先去除用戶體驗,不(bù)過這(zhè)要(yào / yāo)保證你的(de)網站在(zài)沒有 JavaScript也(yě)可以(yǐ)正常運行。在(zài)确定頁面運行正常後,再加載腳本來(lái)實現如拖放和(hé / huò)動畫等更加花哨的(de)效果。


6、預加載

  預加載和(hé / huò)後加載看起來(lái)似乎恰恰相反,但實際上(shàng)預加載是(shì)爲(wéi / wèi)了(le/liǎo)實 現另外一(yī / yì /yí)種目标。預加載是(shì)在(zài)浏覽器空閑時(shí)請求将來(lái)可能會用到(dào)的(de)頁面内容(如圖像、樣式表和(hé / huò)腳本)。使用這(zhè)種方法,當用戶要(yào / yāo)訪問下一(yī / yì /yí)個(gè)頁面時(shí),頁面中的(de)内容 大(dà)部分已經加載到(dào)緩存中了(le/liǎo),因此可以(yǐ)大(dà)大(dà)改善訪問速度。


下面提供了(le/liǎo)幾種預加載方法:

  無條件加載:觸發 onload事件時(shí),直接加載額外的(de)頁面内容。以(yǐ) Google.com爲(wéi / wèi)例,你可以(yǐ)看一(yī / yì /yí)下它的(de) spirit image圖像是(shì)怎樣在(zài) onload中加載的(de)。這(zhè)個(gè) spirit image圖像在(zài) google.com主頁中是(shì)不(bù)需要(yào / yāo)的(de),但是(shì)卻可以(yǐ)在(zài)搜索結果頁面中用到(dào)它。

有條件加載:根據用戶的(de)操作來(lái)有根據地(dì / de)判斷用戶下面可能去往的(de)頁面并相應的(de)預 加載頁面内容。在(zài) search.yahoo.com中你可以(yǐ)看到(dào)如何在(zài)你輸入内容時(shí)加載額外的(de)頁面内容。

  有預期的(de)加載:載入重新設計過的(de)頁面時(shí)使用預加載。這(zhè)種情況經常出(chū)現在(zài)頁面經過重新設計後用戶抱怨“新的(de)頁面看起來(lái)很酷,但是(shì)卻比以(yǐ)前慢”。問題可能出(chū)在(zài) 用戶對于(yú)你的(de)舊站點建立了(le/liǎo)完整的(de)緩存,而(ér)對于(yú)新站點卻沒有任何緩存内容。因此你可以(yǐ)在(zài)訪問新站之(zhī)前就(jiù)加載一(yī / yì /yí)部内容來(lái)避免這(zhè)種結果的(de)出(chū)現。在(zài)你的(de)舊站中利用 浏覽器的(de)空餘時(shí)間加載新站中用到(dào)的(de)圖像的(de)和(hé / huò)腳本來(lái)提高訪問速度。


7、減少 DOM元素數量

  一(yī / yì /yí)個(gè)複雜的(de)頁面意味着需要(yào / yāo)下載更多數據,同時(shí)也(yě)意味着 JavaScript遍曆 DOM的(de)效率越慢。比如當你增加一(yī / yì /yí)個(gè)事件句柄時(shí)在(zài) 500和(hé / huò) 5000個(gè) DOM元素中循環效果肯定是(shì)不(bù)一(yī / yì /yí)樣的(de)。

  大(dà)量的(de) DOM元素的(de)存在(zài)意味着頁面中有可以(yǐ)不(bù)用移除内容隻需要(yào / yāo)替換元素标簽就(jiù)可以(yǐ)精簡的(de)部分。你在(zài)頁面布局中使用表格了(le/liǎo)嗎?你有沒有僅僅爲(wéi / wèi)了(le/liǎo)布局而(ér)引入更多的(de) <div>元素呢?也(yě)許會存在(zài)一(yī / yì /yí)個(gè)适合或者在(zài)語意是(shì)更貼切的(de)标簽可以(yǐ)供你使用。

  YUI CSS utilities 可以(yǐ)給你的(de)布局帶來(lái)巨大(dà)幫助: grids.css可以(yǐ)幫你實現整體布局, font.css和(hé / huò) reset.css可以(yǐ)幫助你移除浏覽器默認格式。它提供了(le/liǎo)一(yī / yì /yí)個(gè)重新審視你頁面中标簽 的(de)機會,比如隻有在(zài)語意上(shàng)有意義時(shí)才使用 <div>,而(ér)不(bù)是(shì)因爲(wéi / wèi)它具有換行效果才使用它。

  DOM 元素數量很容易計算出(chū)來(lái),隻需要(yào / yāo)在(zài) Firebug的(de)控制台内輸入:

document.getElementsByTagName('*').length

  那麽多少個(gè) DOM元素算是(shì)多呢?這(zhè)可以(yǐ)對照有很好标記使用的(de)類似頁面。比如 Yahoo!主頁是(shì)一(yī / yì /yí)個(gè)内容非常多的(de)頁面,但是(shì)它隻使用了(le/liǎo) 700個(gè)元素( HTML标簽)。


8、根據域名劃分頁面内容

  把頁面内容劃分成若幹部分可以(yǐ)使你最大(dà)限度地(dì / de)實現平行下載。由于(yú) DNS查找帶來(lái)的(de)影響你首先要(yào / yāo)确保你使用的(de)域名數量在(zài) 2個(gè)到(dào) 4個(gè)之(zhī)間。例如,你可以(yǐ)把用到(dào)的(de) HTML内容和(hé / huò)動态内容放在(zài) http://www.example.org/ 上(shàng),而(ér)把頁面各種組件(圖片、腳本、 CSS)分别存放在(zài) statics1.example.org和(hé / huò) statics.example.org上(shàng)。

你可在(zài) Tenni Theurer和(hé / huò) Patty Chi合寫的(de)文章 Maximizing Parallel Downloads in the Carpool Lane找到(dào)更多相關信息。


9、使 iframe的(de)數量最小

  ifrmae 元素可以(yǐ)在(zài)父文檔中插入一(yī / yì /yí)個(gè)新的(de) HTML文檔。了(le/liǎo)解 iframe的(de)工作理然後才能更加有效地(dì / de)使用它,這(zhè)一(yī / yì /yí)點很重要(yào / yāo)。


<iframe>優點:

解決加載緩慢的(de)第三方内容如圖标和(hé / huò)廣告等的(de)加載問題

Security sandbox

并行加載腳本

<iframe>的(de)缺點:

即時(shí)内容爲(wéi / wèi)空,加載也(yě)需要(yào / yāo)時(shí)間

會阻止頁面加載

沒有語意


10、不(bù)要(yào / yāo)出(chū)現 404錯誤

   HTTP 請求時(shí)間消耗是(shì)很大(dà)的(de),因此使用 HTTP請求來(lái)獲得一(yī / yì /yí)個(gè)沒有用處的(de)響應(例如 404沒有找到(dào)頁面)是(shì)完全沒有必要(yào / yāo)的(de),它隻會降低用戶體驗而(ér)不(bù)會有一(yī / yì /yí)點好處。

  有些站點把 404錯誤響應頁面改爲(wéi / wèi)“你是(shì)不(bù)是(shì)要(yào / yāo)找 ***”,這(zhè)雖然改進了(le/liǎo)用戶體驗但是(shì)同樣也(yě)會浪費服務器資源(如數據庫等)。最糟糕的(de) 情況是(shì)指向外部 JavaScript的(de)鏈接出(chū)現問題并返回 404代碼。首先,這(zhè)種加載會破壞并行加載;其次浏覽器會把試圖在(zài)返回的(de)404響應内容中找到(dào)可能有用的(de)部分當作 JavaScript代碼來(lái)執行。

二、服務器部分

  • 使用内容分發網絡
  • 爲(wéi / wèi)文件頭指定Expires或Cache-Control
  • Gzip壓縮文件内容
  • 配置ETag
  • 盡早刷新輸出(chū)緩沖
  • 使用GET來(lái)完成AJAX請求
  • 避免空的(de)圖像來(lái)源

11、使用内容分發網絡 
  用戶與你網站服務器的(de)接近程度會影響響應時(shí)間的(de)長短。把你的(de)網站内容分散到(dào)多個(gè)、處于(yú)不(bù)同地(dì / de)域位置的(de)服務器上(shàng)可以(yǐ)加快下載速度。但是(shì)首先我們應該做些什麽呢?
  按地(dì / de)域布置網站内容的(de)第一(yī / yì /yí)步并不(bù)是(shì)要(yào / yāo)嘗試重新架構你的(de)網站讓他(tā)們在(zài)分發服務器上(shàng)正常運行。根據應用的(de)需求來(lái)改變網站結構,這(zhè)可能會包括一(yī / yì /yí)些比較複雜的(de)任 務,如在(zài)服務器間同步Session狀态和(hé / huò)合并數據庫更新等。要(yào / yāo)想縮短用戶和(hé / huò)内容服務器的(de)距離,這(zhè)些架構步驟可能是(shì)不(bù)可避免的(de)。
  要(yào / yāo)記住,在(zài)終端用戶的(de)響應時(shí)間中有80%到(dào)90%的(de)響應時(shí)間用于(yú)下載圖像、樣式表、腳本、Flash等頁面内容。這(zhè)就(jiù)是(shì)網站性能黃金守則。和(hé / huò)重新設計你的(de) 應用程序架構這(zhè)樣比較困難的(de)任務相比,首先來(lái)分布靜态内容會更好一(yī / yì /yí)點。這(zhè)不(bù)僅會縮短響應時(shí)間,而(ér)且對于(yú)内容分發網絡來(lái)說(shuō)它更容易實現。
  内容分發網絡(Content Delivery Network,CDN)是(shì)由一(yī / yì /yí)系列分散到(dào)各個(gè)不(bù)同地(dì / de)理位置上(shàng)的(de)Web服務器組成的(de),它提高了(le/liǎo)網站内容的(de)傳輸速度。用于(yú)向用戶傳輸内容的(de)服務器主要(yào / yāo)是(shì)根據 和(hé / huò)用戶在(zài)網絡上(shàng)的(de)靠近程度來(lái)指定的(de)。例如,擁有最少網絡跳數(network hops)和(hé / huò)響應速度最快的(de)服務器會被選定。
  一(yī / yì /yí)些大(dà)型的(de)網絡公司擁有自己的(de)CDN,但是(shì)使用像Akamai Technologies,Mirror Image Internet,或者Limelight Networks這(zhè)樣的(de)CDN服務成本卻非常高。對于(yú)剛剛起步的(de)企業和(hé / huò)個(gè)人(rén)網站來(lái)說(shuō),可能沒有使用CDN的(de)成本預算,但是(shì)随着目标用戶群的(de)不(bù)斷擴大(dà)和(hé / huò)更加 全球化,CDN就(jiù)是(shì)實現快速響應所必需的(de)了(le/liǎo)。以(yǐ)Yahoo來(lái)說(shuō),他(tā)們轉移到(dào)CDN上(shàng)的(de)網站程序靜态内容節省了(le/liǎo)終端用戶20%以(yǐ)上(shàng)的(de)響應時(shí)間。使用CDN是(shì)一(yī / yì /yí)個(gè)隻需要(yào / yāo)相對簡單地(dì / de)修改代碼實現顯著改善網站訪問速度的(de)方法。


12、爲(wéi / wèi)文件頭指定Expires或Cache-Control 
  這(zhè)條守則包括兩方面的(de)内容:
對于(yú)靜态内容:設置文件頭過期時(shí)間Expires的(de)值爲(wéi / wèi)“Never expire”(永不(bù)過期)
對于(yú)動态内容:使用恰當的(de)Cache-Control文件頭來(lái)幫助浏覽器進行有條件的(de)請求
  網頁内容設計現在(zài)越來(lái)越豐富,這(zhè)就(jiù)意味着頁面中要(yào / yāo)包含更多的(de)腳本、樣式表、圖片和(hé / huò)Flash。第一(yī / yì /yí)次訪問你頁面的(de)用戶就(jiù)意味着進行多次的(de)HTTP請求,但 是(shì)通過使用Expires文件頭就(jiù)可以(yǐ)使這(zhè)樣内容具有緩存性。它避免了(le/liǎo)接下來(lái)的(de)頁面訪問中不(bù)必要(yào / yāo)的(de)HTTP請求。Expires文件頭經常用于(yú)圖像文件, 但是(shì)應該在(zài)所有的(de)内容都使用他(tā),包括腳本、樣式表和(hé / huò)Flash等。
  浏覽器(和(hé / huò)代理)使用緩存來(lái)減少HTTP請求的(de)大(dà)小和(hé / huò)次數以(yǐ)加快頁面訪問速度。Web服務器在(zài)HTTP響應中使用Expires文件頭來(lái)告訴客戶端内容需 要(yào / yāo)緩存多長時(shí)間。下面這(zhè)個(gè)例子(zǐ)是(shì)一(yī / yì /yí)個(gè)較長時(shí)間的(de)Expires文件頭,它告訴浏覽器這(zhè)個(gè)響應直到(dào)2010年4月15日才過期。
      Expires: Thu, 15 Apr 2010 20:00:00 GMT 
  如果你使用的(de)是(shì)Apache服務器,可以(yǐ)使用ExpiresDefault來(lái)設定相對當前日期的(de)過期時(shí)間。下面這(zhè)個(gè)例子(zǐ)是(shì)使用ExpiresDefault來(lái)設定請求時(shí)間後10年過期的(de)文件頭:
      ExpiresDefault "access plus 10 years" 
  要(yào / yāo)切記,如果使用了(le/liǎo)Expires文件頭,當頁面内容改變時(shí)就(jiù)必須改變内容的(de)文件名。依Yahoo!來(lái)說(shuō)我們經常使用這(zhè)樣的(de)步驟:在(zài)内容的(de)文件名中加上(shàng)版 本号,如yahoo_2.0.6.js。
  使用Expires文件頭隻有會在(zài)用戶已經訪問過你的(de)網站後才會起作用。當用戶首次訪問你的(de)網站時(shí)這(zhè)對減少HTTP請求次數來(lái)說(shuō)是(shì)無效的(de),因爲(wéi / wèi)浏覽器的(de)緩 存是(shì)空的(de)。因此這(zhè)種方法對于(yú)你網站性能的(de)改進情況要(yào / yāo)依據他(tā)們“預緩存”存在(zài)時(shí)對你頁面的(de)點擊頻率(“預緩存”中已經包含了(le/liǎo)頁面中的(de)所有内容)。 Yahoo!建立了(le/liǎo)一(yī / yì /yí)套測量方法,我們發現所有的(de)頁面浏覽量中有75~85%都有“預緩存”。通過使用Expires文件頭,增加了(le/liǎo)緩存在(zài)浏覽器中内容的(de) 數量,并且可以(yǐ)在(zài)用戶接下來(lái)的(de)請求中再次使用這(zhè)些内容,這(zhè)甚至都不(bù)需要(yào / yāo)通過用戶發送一(yī / yì /yí)個(gè)字節的(de)請求。