加速網站的最佳實踐

Exceptional Performance團隊已經肯定了許多快速製做網頁的最佳實踐。javascript

按類別篩選: Content Server Cookie CSS JavaScript Images Mobile All
最小化HTTP請求 tag: contentphp

最終用戶響應時間的80%用於前端。大部分時間都在下載頁面中的全部組件:圖像,樣式表,腳本,Flash等。減小組件數量反過來減小了呈現頁面所需的HTTP請求數量。這是更快頁面的關鍵。css

減小頁面中組件數量的一種方法是簡化頁面設計。但有沒有辦法構建內容更豐富的頁面,同時還能實現快速響應時間?如下是一些減小HTTP請求數量的技術,同時仍支持豐富的頁面設計。html

組合文件是一種經過將全部腳本組合到單個腳本中來減小HTTP請求數量的方法,而且相似地將全部CSS組合到單個樣式表中。當腳本和樣式表在不一樣頁面之間變化時,組合文件更具挑戰性,但使這部分發布過程能夠縮短響應時間。前端

CSS Sprites是減小圖像請求數量的首選方法。將背景圖像合併爲單個圖像,並使用CSSbackground-image和background-position屬性顯示所需的圖像片斷。java

圖像地圖將多個圖像組合成單個圖像。總體大小大體相同,但減小HTTP請求的數量會加快頁面的速度。圖像映射僅在圖像在頁面中是連續的時才起做用,例如導航欄。定義圖像映射的座標多是乏味且容易出錯的。使用圖像地圖進行導航也沒法訪問,所以不建議使用。node

內聯圖像使用data:URL方案將圖像數據嵌入實際頁面中。這能夠增長HTML文檔的大小。將內嵌圖像組合到(緩存的)樣式表中是一種減小HTTP請求並避免增長頁面大小的方法。並不是全部主流瀏覽器都支持內嵌圖像。算法

減小頁面中HTTP請求的數量是能夠開始的地方。這是提升首次訪問者性能的最重要指南。正如Tenni Theurer的博客文章瀏覽器緩存使用 - 暴露!,您網站的每日訪問者中有40-60%使用空緩存。讓這些首次訪問者快速訪問頁面是得到更好用戶體驗的關鍵。數據庫

使用內容分發網絡 tag: serverexpress

用戶與Web服務器的距離會對響應時間產生影響。在多個地理位置分散的服務器上部署內容將使您的頁面從用戶的角度加載更快。可是你應該從哪裏開始呢?

做爲實現地理位置分散的內容的第一步,請勿嘗試從新設計Web應用程序以在分佈式體系結構中工做。根據應用程序的不一樣,更改體系結構可能包括使人生畏的任務,例如同步會話狀態和跨服務器位置複製數據庫事務。嘗試縮短用戶與您的內容之間的距離可能會延遲或永遠不會經過此應用程序架構步驟。

請記住,最終用戶響應時間的80-90%用於下載頁面中的全部組件:圖像,樣式表,腳本,Flash等。這是性能黃金規則。而不是從從新設計應用程序架構的艱鉅任務開始,最好先分散靜態內容。這不只能夠縮短響應時間,並且因爲內容交付網絡,它更容易實現。

內容傳送網絡(CDN)是分佈在多個位置的Web服務器的集合,以更有效地向用戶傳送內容。選擇用於向特定用戶傳送內容的服務器一般基於網絡鄰近度的度量。例如,選擇具備最少網絡跳躍的服務器或具備最快響應時間的服務器。

一些大型互聯網公司擁有本身的CDN,但使用CDN服務提供商(如Akamai Technologies,EdgeCast或level3)具備成本效益。對於初創公司和私人網站來講,CDN服務的成本可能太高,但隨着您的目標受衆變得愈來愈大並變得更加全球化,CDN對於實現快速響應時間是必要的。在Yahoo!中,將靜態內容從其應用程序Web服務器移動到CDN(如上所述的第三方以及Yahoo本身的CDN)的屬性將最終用戶響應時間提升了20%或更多。切換到CDN是一個相對容易的代碼更改,將顯着提升您的網站的速度。

添加Expires或Cache-Control標頭 tag: server

這條規則有兩個方面:

對於靜態組件:經過設置遠期將來Expires標頭實現「永不過時」策略
對於動態組件:使用適當的Cache-Control標頭來幫助瀏覽器處理條件請求

網頁設計愈來愈豐富,這意味着頁面中有更多的腳本,樣式表,圖像和Flash。您的頁面的首次訪問者可能必須發出多個HTTP請求,但經過使用Expires標頭,您可使這些組件可緩存。這能夠避免後續頁面查看中沒必要要的HTTP請求。Expires頭文件一般與圖像一塊兒使用,但它們應該用於全部組件,包括腳本,樣式表和Flash組件。

瀏覽器(和代理)使用緩存來減小HTTP請求的數量和大小,從而加快網頁加載速度。Web服務器使用HTTP響應中的Expires頭來告訴客戶端能夠緩存組件多長時間。這是一個遙遠的將來Expires標題,告訴瀏覽器這個響應在2010年4月15日以前不會過期。

到期日:2010年4月15日星期四20:00:00 GMT

若是您的服務器是Apache,請使用ExpiresDefault指令設置相對於當前日期的到期日期。ExpiresDefault指令的這個示例將Expires日期設置爲距請求時間10年。

ExpiresDefault「訪問加10年」

請記住,若是您使用遠期的Expires標頭,則必須在組件更改時更改組件的文件名。在Yahoo! 咱們常常將此步驟做爲構建過程的一部分:版本號嵌入在組件的文件名中,例如,yahoo_2.0.6.js。

使用遠期Expires標頭僅在用戶訪問過您的網站後纔會影響網頁瀏覽量。當用戶第一次訪問您的站點而且瀏覽器的緩存爲空時,它對HTTP請求的數量沒有影響。所以,此性能改進的影響取決於用戶使用已準備好的緩存命中您的頁面的頻率。(「已準備好的緩存」已包含頁面中的全部組件。)咱們在Yahoo!上測量了這一點。並發現帶有固定緩存的頁面查看次數爲75-85%。經過使用遠期的Expires標頭,您能夠增長瀏覽器緩存的組件數量,並在後續頁面視圖中重複使用,而無需經過用戶的Internet鏈接發送單個字節。

Gzip組件 tag: server

經過前端工程師作出的決策,能夠顯着減小在網絡上傳輸HTTP請求和響應所需的時間。確實,最終用戶的帶寬速度,互聯網服務提供商,與對等交換點的距離等都超出了開發團隊的控制範圍。可是還有其餘變量會影響響應時間。壓縮經過減小HTTP響應的大小來減小響應時間。

從HTTP / 1.1開始,Web客戶端表示支持使用HTTP請求中的Accept-Encoding標頭進行壓縮。

Accept-Encoding:gzip,deflate

若是Web服務器在請求中看到此標頭,它可能會使用客戶端列出的方法之一壓縮響應。Web服務器經過響應中的Content-Encoding標頭向Web客戶端通知此狀況。

Content-Encoding: gzip

Gzip是目前最流行,最有效的壓縮方法。它由GNU項目開發,並由RFC 1952標準化。您可能會看到的惟一其餘壓縮格式是放氣,但效果較差且不太受歡迎。

Gzipping一般將響應大小減小約70%。今天大約90%的互聯網流量經過聲稱支持gzip的瀏覽器傳播。若是你使用Apache,配置gzip的模塊取決於你的版本:Apache 1.3使用mod_gzip而Apache 2.x使用mod_deflate。

瀏覽器和代理存在已知問題,這些問題可能致使瀏覽器指望的內容與壓縮內容相關的內容不匹配。幸運的是,隨着舊瀏覽器的使用逐漸減小,這些邊緣狀況正在逐漸減小。Apache模塊經過自動添加適當的Vary響應頭來提供幫助。

服務器根據文件類型選擇gzip的內容,但一般在他們決定壓縮的內容方面受到限制。大多數網站都會gzip他們的HTML文檔。gzip你的腳本和樣式表也是值得的,但不少網站都錯過了這個機會。實際上,壓縮包括XML和JSON在內的任何文本響應都是值得的。不該對圖像和PDF文件進行gzip壓縮,由於它們已通過壓縮。試圖對它們進行gzip不只浪費CPU,並且可能會增長文件大小。

儘量多地壓縮文件類型是減輕頁面重量和加速用戶體驗的簡便方法。

將樣式表放在頂部 tag: css

在研究Yahoo!的性能時,咱們發現將樣式表移動到文檔HEAD會使頁面看起來加載速度更快。這是由於將樣式表放在HEAD中容許頁面逐步呈現。

關注性能的前端工程師但願頁面逐步加載; 也就是說,咱們但願瀏覽器儘快顯示它擁有的任何內容。這對於具備大量內容的頁面和對較慢Internet鏈接的用戶尤爲重要。爲用戶提供視覺反饋(例如進度指示器)的重要性已獲得很好的研究和記錄。在咱們的例子中,HTML頁面是進度指示器!當瀏覽器逐步加載頁面時,標題,導航欄,頂部的徽標等都做爲等待頁面的用戶的視覺反饋。這改善了總體用戶體驗。

將樣式表放在文檔底部附近的問題是它禁止在許多瀏覽器(包括Internet Explorer)中逐行渲染。這些瀏覽器會阻止渲染,以免在樣式發生變化時重繪頁面元素。用戶查看空白頁面時卡住了。

的HTML規範明確指出,樣式表是被包括在網頁的HEAD:「與A,[LINK]能夠僅出如今一個文檔的HEAD部分,儘管它可能出現任意次數」。這些替代品,空白的白色屏幕或無風格內容的閃光都是值得冒險的。最佳解決方案是遵循HTML規範並在文檔HEAD中加載樣式表。

把腳本放在底部 tag: javascript

腳本引發的問題是它們阻止了並行下載。的HTTP / 1.1規範建議的瀏覽器下載不超過兩種組分在每主機名平行。若是您從多個主機名提供圖像,則能夠並行執行兩次以上的下載。可是,在下載腳本時,即便在不一樣的主機名上,瀏覽器也不會啓動任何其餘下載。

在某些狀況下,將腳本移到底部並不容易。例如,若是腳本用於document.write插入頁面內容的一部分,則沒法在頁面中向下移動。可能還存在範圍問題。在許多狀況下,有辦法解決這些問題。

常常出現的另外一種建議是使用延遲腳本。該DEFER屬性代表該腳本不包含document.write,而且是瀏覽器能夠繼續呈現的線索。不幸的是,Firefox不支持該DEFER屬性。在Internet Explorer中,腳本可能會延遲,但不是所需的。若是能夠延遲腳本,也能夠將其移動到頁面底部。這將使您的網頁加載速度更快。

避免使用CSS表達式 tag: css

CSS表達式是一種動態設置CSS屬性的強大(且危險)方法。從版本5開始,它們在Internet Explorer中受支持,但從IE8開始不推薦使用。例如,可使用CSS表達式將背景顏色設置爲每小時交替:

background-color: expression( (new Date()).getHours()%2 ? "#B8D4FF" : "#F08A00" );

如此處所示,該expression方法接受JavaScript表達式。CSS屬性設置爲評估JavaScript表達式的結果。expression其餘瀏覽器會忽略該方法,所以在Internet Explorer中設置屬性以在跨瀏覽器建立一致體驗時很是有用。

表達式的問題在於它們的評估頻率高於大多數人的預期。它們不只在頁面呈現和調整大小時進行評估,並且在頁面滾動時甚至在用戶將鼠標移動到頁面上時進行評估。在CSS表達式中添加計數器可讓咱們跟蹤CSS表達式的計算時間和頻率。在頁面上移動鼠標能夠輕鬆生成10,000多個評估。

減小CSS表達式求值次數的一種方法是使用一次性表達式,其中第一次計算表達式時,它將style屬性設置爲顯式值,這將替換CSS表達式。若是必須在頁面的整個生命週期中動態設置樣式屬性,則使用事件處理程序而不是CSS表達式是另外一種方法。若是必須使用CSS表達式,請記住它們可能會被評估數千次,並可能影響頁面的性能。

使JavaScript和CSS外部 tag: javascript, css

其中許多性能規則都涉及外部組件的管理方式。可是,在出現這些考慮因素以前,您應該提出一個更基本的問題:JavaScript和CSS是否應該包含在外部文件中,仍是內嵌在頁面中?

在現實世界中使用外部文件一般會產生更快的頁面,由於瀏覽器會緩存JavaScript和CSS文件。每次請求HTML文檔時,都會下載HTML文檔中內聯的JavaScript和CSS。這減小了所需的HTTP請求數,但增長了HTML文檔的大小。另外一方面,若是JavaScript和CSS位於瀏覽器緩存的外部文件中,則HTML文檔的大小會減小,而不會增長HTTP請求的數量。

所以,關鍵因素是外部JavaScript和CSS組件相對於請求的HTML文檔數量的緩存頻率。這個因素雖然難以量化,但可使用各類指標進行衡量。若是您站點上的用戶每一個會話有多個頁面查看,而且您的許多頁面重複使用相同的腳本和樣式表,則緩存的外部文件可能會帶來更大的潛在好處。

許多網站都處於這些指標的中間。對於這些站點,最佳解決方案一般是將JavaScript和CSS部署爲外部文件。內聯的惟一例外是主頁,例如Yahoo!的首頁和My Yahoo! 。每一個會話具備不多(可能只有一個)頁面視圖的主頁可能會發現內聯JavaScript和CSS會致使更快的最終用戶響應時間。

對於一般是許多頁面視圖中的第一個的首頁,有一些技術能夠利用內聯提供的HTTP請求的減小,以及經過使用外部文件實現的緩存優點。其中一種技術是在首頁中內聯JavaScript和CSS,但在頁面加載完成後動態下載外部文件。後續頁面將引用應該已存在於瀏覽器緩存中的外部文件。

減小DNS查找 tag: content

域名系統(DNS)將主機名映射到IP地址,就像電話簿將人們的姓名映射到他們的電話號碼同樣。當您在瀏覽器中鍵入www.yahoo.com時,瀏覽器聯繫的DNS解析器將返回該服務器的IP地址。DNS有成本。DNS一般須要20-120毫秒才能查找給定主機名的IP地址。在DNS查找完成以前,瀏覽器沒法今後主機名下載任何內容。

緩存DNS查找以得到更好的性能。此緩存能夠在由用戶的ISP或局域網維護的特殊緩存服務器上進行,但在單個用戶的計算機上也存在緩存。DNS信息保留在操做系統的DNS緩存中(Microsoft Windows上的「DNS客戶端服務」)。大多數瀏覽器都有本身的緩存,與操做系統的緩存分開。只要瀏覽器將DNS記錄保存在本身的緩存中,它就不會因操做系統請求記錄而煩惱。

默認狀況下,Internet Explorer會將DNS查找緩存30分鐘,具體 DnsCacheTimeout取決於註冊表設置。Firefox將DNS查找緩存1分鐘,由network.dnsCacheExpiration配置設置控制。(Fasterfox將此更改成1小時。)

當客戶端的DNS緩存爲空(對於瀏覽器和操做系統)時,DNS查找的數量等於網頁中惟一主機名的數量。這包括頁面的URL,圖像,腳本文件,樣式表,Flash對象等中使用的主機名。減小惟一主機名的數量可減小DNS查找的數量。

減小惟一主機名的數量有可能減小頁面中發生的並行下載量。避免DNS查找會縮短響應時間,但減小並行下載可能會縮短響應時間。個人準則是將這些組件分紅至少兩個但不超過四個主機名。這致使在減小DNS查找和容許高度並行下載之間的良好折衷。

縮小JavaScript和CSS tag: javascript, css

縮小是從代碼中刪除沒必要要的字符以減少其大小從而改善加載時間的作法。縮小代碼時,將刪除全部註釋,以及不須要的空格字符(空格,換行符和製表符)。在JavaScript的狀況下,這改善了響應時間性能,由於下載文件的大小減少了。用於縮小JavaScript代碼的兩種流行工具是JSMin和YUI Compressor。YUI壓縮器也能夠縮小CSS。

混淆是能夠應用於源代碼的替代優化。它比縮小更復雜,所以更容易因混淆步驟自己而產生錯誤。在對美國十大頂級網站的調查中,縮小規模縮小了21%,而混淆縮小了25%。儘管混淆具備更高的大小縮減,但縮小JavaScript的風險較小。

除了縮小外部腳本和樣式以外,內聯<script>和<style>塊也能夠而且也應該縮小。即便你gzip你的腳本和樣式,縮小它們仍然會減少5%或更多的大小。隨着JavaScript和CSS的使用和大小的增長,縮小代碼所節省的成本也會增長。

避免重定向 tag: content

使用301和302狀態代碼完成重定向。如下是301響應中HTTP標頭的示例:

HTTP/1.1 301 Moved Permanently
  Location: http://example.com/newuri
  Content-Type: text/html

瀏覽器自動將用戶帶到該Location字段中指定的URL 。重定向所需的全部信息都在標題中。響應的主體一般是空的。儘管有其名稱,但實際上不會緩存301或302響應,除非其餘標題(例如Expires或Cache-Control表示它應該是)。元刷新標記和JavaScript是將用戶定向到不一樣URL的其餘方法,但若是必須進行重定向,則首選技術是使用標準3xx HTTP狀態代碼,主要是爲了確保後退按鈕正常工做。

要記住的主要事情是重定向會下降用戶體驗。在用戶和HTML文檔之間插入重定向會延遲頁面中的全部內容,由於頁面中的任何內容都沒法呈現,而且在HTML文檔到達以前不會開始下載任何組件。

最浪費的重定向之一常常發生,Web開發人員一般不瞭解它。當URL中缺乏尾部斜槓(/)時會發生這種狀況。例如,轉到http://astrology.yahoo.com/as...,其中包含重定向到http://astrology.yahoo.com/as...(注意添加的尾部斜槓)。若是您使用的是Apache處理程序,則可使用Aliasor mod_rewrite或DirectorySlash指令在Apache中修復此問題。

將舊網站鏈接到新網站是重定向的另外一種常見用途。其餘包括鏈接網站的不一樣部分並基於特定條件(瀏覽器類型,用戶賬戶類型等)指導用戶。使用重定向鏈接兩個網站很簡單,只須要不多的額外編碼。雖然在這些狀況下使用重定向會下降開發人員的複雜性,但會下降用戶體驗。使用重定向的替代方法包括使用Alias以及mod_rewrite兩個代碼路徑是否託管在同一服務器上。若是域名更改是使用重定向的緣由,則另外一種方法是建立CNAME(建立從一個域名指向另外一個域名的別名的DNS記錄)與Alias或組合mod_rewrite。

刪除重複的腳本 tag: javascript

在一個頁面中兩次包含相同的JavaScript文件會損害性能。這並不像你想象的那麼不尋常。對美國十大頂級網站的評論顯示,其中兩個網站包含重複的腳本。兩個主要因素會增長腳本在單個網頁中重複的概率:團隊規模和腳本數量。當它發生時,重複的腳本會經過建立沒必要要的HTTP請求和浪費的JavaScript執行來損害性能。

沒必要要的HTTP請求在Internet Explorer中發生,但在Firefox中不發生。在Internet Explorer中,若是外部腳本包含兩次且不可緩存,則在頁面加載期間會生成兩個HTTP請求。即便腳本是可緩存的,當用戶從新加載頁面時也會發生額外的HTTP請求。

除了生成浪費的HTTP請求以外,還浪費了屢次評估腳本的時間。不管腳本是否可緩存,這種冗餘的JavaScript執行都會在Firefox和Internet Explorer中執行。

避免意外包含相同腳本兩次的一種方法是在模板系統中實現腳本管理模塊。包含腳本的典型方法是在HTML頁面中使用SCRIPT標記。

<script type="text/javascript" src="menu_1.0.17.js"></script>

PHP中的另外一種選擇是建立一個名爲的函數insertScript。

<?php insertScript("menu.js") ?>

除了防止屢次插入相同的腳本以外,此函數還能夠處理腳本的其餘問題,例如依賴性檢查和向腳本文件名添加版本號以支持遠期的Expires頭。

配置ETag tag: server

實體標記(ETag)是Web服務器和瀏覽器用於肯定瀏覽器緩存中的組件是否與源服務器上的組件匹配的機制。(「實體」是另外一個詞「組件」:圖像,腳本,樣式表等)。添加ETag以提供驗證比上次修改日期更靈活的實體的機制。ETag是惟一標識組件的特定版本的字符串。惟一的格式約束是引用字符串。源服務器使用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傳遞迴原始服務器。若是ETag匹配,則返回304狀態代碼,從而將響應減小12195字節。

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

ETag的問題在於它們一般使用屬性構建,這些屬性使它們對託管站點的特定服務器是惟一的。當瀏覽器從一個服務器獲取原始組件並稍後嘗試在不一樣服務器上驗證該組件時,ETag將不匹配,這種狀況在使用服務器集羣處理請求的網站上很是常見。默認狀況下,Apache和IIS都在ETag中嵌入數據,這大大下降了在具備多個服務器的網站上成功進行有效性測試的概率。

Apache 1.3和2.x的ETag格式是inode-size-timestamp。雖然給定文件能夠跨多個服務器駐留在同一目錄中,而且具備相同的文件大小,權限,時間戳等,但它的inode在服務器與下一個服務器之間是不一樣的。

IIS 5.0和6.0與ETag有相似的問題。IIS上ETag的格式是Filetimestamp:ChangeNumber。A ChangeNumber是用於跟蹤IIS配置更改的計數器。這是不太可能的ChangeNumber是後面整個網站的全部IIS服務器相同。

最終結果是Apache和IIS生成的ETag對於徹底相同的組件從一臺服務器到另外一臺服務器不匹配。若是ETag不匹配,則用戶不會收到ETag設計的小的,快速的304響應; 相反,他們將得到正常的200響應以及組件的全部數據。若是您只在一臺服務器上託管您的網站,這不是問題。可是,若是您有多個服務器託管您的網站,而且您正在使用具備默認ETag配置的Apache或IIS,則您的用戶正在變慢頁面,您的服務器負載更高,您正在消耗更大的帶寬,而且代理服務器沒有有效地緩存您的內容。即便您的組件具備遠期Expires標頭,每當用戶點擊從新加載或刷新時,仍會發出條件GET請求。

若是您沒有利用ETag提供的靈活驗證模型,最好只刪除ETag。該Last-Modified頭驗證基於對組件的時間戳。刪除ETag會減小響應和後續請求中HTTP標頭的大小。此Microsoft支持文章介紹瞭如何刪除ETag。在Apache中,只需將如下行添加到Apache配置文件便可:

FileETag none

使Ajax能夠緩存 tag: content

Ajax的一個優勢是它爲用戶提供即時反饋,由於它從後端Web服務器異步請求信息。可是,使用Ajax並不能保證用戶不會在等待那些異步JavaScript和XML響應返回時大拇指。在許多應用程序中,用戶是否保持等待取決於Ajax的使用方式。例如,在基於Web的電子郵件客戶端中,用戶將一直等待Ajax請求的結果,以查找符合其搜索條件的全部電子郵件。重要的是要記住「異步」並不意味着「瞬時」。

爲了提升性能,優化這些Ajax響應很是重要。提升Ajax性能的最重要方法是使響應可緩存,如添加過時或緩存控制標頭中所述。其餘一些規則也適用於Ajax:
Gzip組件
減小DNS查找
縮小JavaScript
避免重定向
配置ETag

咱們來看一個例子。Web 2.0電子郵件客戶端可能使用Ajax下載用戶的通信簿以進行自動完成。若是用戶自上次使用電子郵件Web應用程序以來未修改過她的地址簿,則能夠從緩存中讀取先前的地址簿響應,若是該Ajax響應可使用未來的Expires或Cache-Control標頭進行緩存。必須通知瀏覽器什麼時候使用先前緩存的地址簿響應而不是請求新的地址簿響應。這能夠經過向地址簿Ajax URL添加時間戳來完成,該時間戳指示用戶上次修改其地址簿的時間,例如,&t=1190241612。若是自上次下載後地址簿還沒有被修改,則時間戳將相同,而且將從瀏覽器的緩存中讀取地址簿,從而消除額外的HTTP往返。若是用戶修改了地址簿,則時間戳確保新URL與緩存的響應不匹配,瀏覽器將請求更新的地址簿條目。

即便您的Ajax響應是動態建立的,而且可能僅適用於單個用戶,它們仍然能夠緩存。這樣作可使您的Web 2.0應用程序更快。

儘早沖洗緩衝液 tag: server

當用戶請求頁面時,後端服務器可能須要200到500毫秒才能將HTML頁面拼接在一塊兒。在此期間,瀏覽器在等待數據到達時處於空閒狀態。在PHP中,您有函數flush()。它容許您將部分準備好的HTML響應發送到瀏覽器,以便瀏覽器能夠在後端忙於HTML頁面的其他部分時開始獲取組件。這種好處主要出如今繁忙的後端或輕量級前端。

考慮刷新的好地方就在HEAD以後,由於頭部的HTML一般更容易生成,而且它容許您包含任何CSS和JavaScript文件,以便瀏覽器在後端處理時並行地開始獲取。

例:

... <!-- css, js -->
</head>
<?php flush(); ?>
<body>
  ... <!-- content -->

雅虎 搜索開創性研究和真實用戶測試,以證實使用此技術的好處。

最佳

使用GET進行AJAX請求 tag: server

在雅虎 郵件團隊發現,在使用時XMLHttpRequest,POST在瀏覽器中實現爲兩步過程:首先發送標頭,而後發送數據。所以最好使用GET,它只須要一個TCP數據包發送(除非你有不少cookie)。IE中的最大URL長度爲2K,所以若是發送的數據超過2K,則可能沒法使用GET。

一個有趣的反作用是沒有實際發佈任何數據的POST就像GET同樣。根據HTTP規範,GET用於檢索信息,所以當您僅請求數據時,使用GET是有意義的(語義上),而不是將數據發送到服務器端存儲。

最佳

後載組件 tag: content

您能夠仔細查看您的頁面並問本身:「最初渲染頁面絕對須要什麼?」。其他的內容和組件能夠等待。

JavaScript是在onload事件以前和以後拆分的理想候選者。例如,若是您有執行拖放和動畫的JavaScript代碼和庫,則能夠等待,由於在初始渲染以後拖動頁面上的元素。其餘尋找後期加載候選者的地方包括隱藏內容(用戶操做後顯示的內容)和首屏下方的圖像。

幫助您完成工做的工具:YUI Image Loader容許您將圖像延遲到摺疊下方,YUI Get實用程序是一種簡單的方法,能夠動態地包含JS和CSS。在野外的例子看看雅虎!打開Firebug網絡面板的主頁。

當性能目標與其餘Web開發最佳實踐一致時,這是很好的。在這種狀況下,漸進加強的想法告訴咱們,JavaScript在受支持時能夠改善用戶體驗,但您必須確保即便沒有JavaScript也能正常工做。所以,在確保頁面正常工做以後,您可使用一些後期加載的腳原本加強它,這些腳本能夠爲您提供更多的花俏功能,例如拖放和動畫。

最佳

預加載組件 tag: content

預加載可能看起來與後加載相反,但它實際上有不一樣的目標。經過預加載組件,您能夠利用瀏覽器空閒的時間並請求未來須要的組件(如圖像,樣式和腳本)。這樣,當用戶訪問下一頁時,您能夠將大部分組件放在緩存中,而且您的頁面將爲用戶加載更快。

實際上有幾種類型的預加載:

無條件預加載 - 一旦onload觸發,你就能夠繼續獲取一些額外的組件。請訪問google.com,瞭解如何請求加載精靈圖片。google.com主頁上不須要此精靈圖片,但在連續搜索結果頁面上須要此精靈圖片。
條件預加載 - 基於用戶操做,您能夠進行有根據的猜想,即用戶前進的位置並相應地預加載。在search.yahoo.com上,您能夠看到在開始輸入輸入框後如何請求一些額外的組件。
預期的預加載 - 在啓動從新設計以前提早預加載。常常在從新設計以後聽到:「新網站很酷,但比之前慢」。部分問題多是用戶使用完整緩存訪問舊網站,但新網站始終是空緩存體驗。您能夠經過在啓動從新設計以前預加載某些組件來緩解此反作用。您的舊站點可使用瀏覽器空閒的時間並請求新站點將使用的圖像和腳本
最佳

減小DOM元素的數量 tag: content

複雜頁面意味着要下載更多字節,這也意味着JavaScript中的DOM訪問速度更慢。例如,當您想要添加事件處理程序時,若是在頁面上循環遍歷500或5000個DOM元素,則會有所不一樣。

大量的DOM元素多是一種症狀,即應該經過頁面標記來改進,而沒必要刪除內容。您是否使用嵌套表進行佈局?您是否<div>只是爲了解決佈局問題而投入更多?也許有一種更好,更語義正確的標記方式。

YUI CSS實用程序 提供了很好的佈局幫助:grids.css能夠幫助您完成總體佈局,fonts.css和reset.css能夠幫助您去除瀏覽器的默認格式。這是一個從新開始並考慮標記的機會,例如,<div>只有在語義上有意義時才使用s,而不是由於它呈現新行。

DOM元素的數量很容易測試,只需鍵入Firebug的控制檯:
document.getElementsByTagName('*').length

有多少DOM元素太多了?檢查具備良好標記的其餘相似頁面。例如雅虎!主頁是一個很是繁忙的頁面,仍然不到700個元素(HTML標記)。

跨域拆分組件 tag: content

拆分組件容許您最大化並行下載。因爲DNS查詢懲罰,請確保您使用的域名不超過2-4個。例如,您能夠託管HTML和動態內容,www.example.org 並在static1.example.org和之間拆分靜態組件static2.example.org

有關更多信息,請查看Tenni Theurer和Patty Chi的「 在Carpool Lane中最大化並行下載 」。

最小化iframe數量 tag: content

iframe容許將HTML文檔插入父文檔中。瞭解iframe如何運做以便有效使用很是重要。

<iframe> 優勢:

幫助緩慢的第三方內容,如徽章和廣告
安全沙箱
並行下載腳本
<iframe> 缺點:

即便空白也要花錢
阻止頁面onload
非語義

沒有404s tag: content

HTTP請求很昂貴,所以發出HTTP請求並得到無用的響應(即404 Not Found)是徹底不必的,而且會在沒有任何好處的狀況下減慢用戶體驗。

有些網站有幫助404「你的意思是X?」,這對用戶體驗頗有好處,但也浪費了服務器資源(好比數據庫等)。特別糟糕的是當外部JavaScript的連接錯誤而且結果是404時。首先,此下載將阻止並行下載。接下來,瀏覽器可能會嘗試解析404響應主體,就像它是JavaScript代碼同樣,試圖找到可用的東西。

減小Cookie大小 tag: cookie

HTTP cookie的使用有多種緣由,例如身份驗證和個性化。有關cookie的信息在Web服務器和瀏覽器之間的HTTP標頭中進行交換。保持cookie的大小盡量低是很是重要的,以儘可能減小對用戶響應時間的影響。

欲瞭解更多信息,請查看 Tenni Theurer和Patty Chi撰寫的「當Cookie崩潰時」。這項研究的主要內容:

消除沒必要要的cookie
保持cookie大小盡量低,以儘可能減小對用戶響應時間的影響
請注意在適當的域級別設置cookie,以避免其餘子域受到影響
適當地設置過時日期。較早的Expires日期或者沒有更早刪除cookie,從而改善了用戶響應時間
最佳

對組件使用無Cookie域 tag: cookie

當瀏覽器發出靜態圖像請求並將cookie與請求一塊兒發送時,服務器對這些cookie沒有任何用處。因此他們只是沒有充分理由建立網絡流量。您應該確保使用無cookie請求請求靜態組件。建立一個子域並在那裏託管全部靜態組件。

若是您的域名是www.example.org,您能夠託管您的靜態組件static.example.org。可是,若是您已經在頂級域上設置了cookie example.org而不是www.example.org,則全部請求都 static.example.org將包含這些cookie。在這種狀況下,您能夠購買一個全新的域,在那裏託管您的靜態組件,並保持此域無cookie。雅虎 用途yimg.com,YouTube使用ytimg.com,亞馬遜使用images-amazon.com等。

在無cookie域上託管靜態組件的另外一個好處是,某些代理可能拒絕緩存使用cookie請求的組件。在相關說明中,若是您想知道是否應該使用example.org或www.example.org做爲主頁,請考慮cookie的影響。省略www會讓您別無選擇,只能寫入cookie *.example.org,所以出於性能緣由,最好使用www子域並將cookie寫入該子域。

最小化DOM訪問 tag: javascript

使用JavaScript訪問DOM元素的速度很慢,所以爲了得到響應更快的頁面,您應該:

緩存對訪問元素的引用
更新節點「離線」,而後將它們添加到樹中
避免使用JavaScript修復佈局
有關更多信息,請查看 Julien Lecomte 的YUI影院的 「高性能Ajax應用程序」。

開發智能事件處理程序 tag: javascript

有時頁面感受響應性較差,由於過多的事件處理程序附加到DOM樹的不一樣元素,而後執行得太頻繁。這就是爲何使用事件委託是一個很好的方法。若是a中有10個按鈕div,則只將一個事件處理程序附加到div包裝器,而不是每一個按鈕一個處理程序。事件冒出來,這樣你就能夠捕捉事件並找出它來自哪一個按鈕。

您也不須要等待onload事件以便開始使用DOM樹執行某些操做。一般,您只須要在樹中訪問要訪問的元素。您沒必要等待下載全部圖像。 DOMContentLoaded是您可能考慮使用的事件而不是onload,但在全部瀏覽器中均可用以前,您可使用具備方法的YUI事件實用程序onAvailable。

有關更多信息,請查看 Julien Lecomte 的YUI影院的 「高性能Ajax應用程序」。

最佳

在@import上選擇<link> tag: css

以前的最佳實踐之一聲明CSS應位於頂部以容許漸進式渲染。

在IE中,@import行爲與<link>在頁面底部使用相同,所以最好不要使用它。

避免過濾器 tag: css

IE專有的AlphaImageLoader過濾器旨在解決IE版本<7中的半透明真彩色PNG的問題。該過濾器的問題在於它在下載圖像時阻止渲染並凍結瀏覽器。它還會增長內存消耗,而且每一個元素應用,而不是每一個圖像,所以問題成倍增長。

最好的方法是AlphaImageLoader徹底避免使用優雅降級的PNG8,這在IE中很好。若是你絕對須要AlphaImageLoader,使用下劃線黑客_filter不會懲罰你的IE7 +用戶。

優化圖像 tag: images

設計師完成爲您的網頁建立圖像後,在將這些圖像FTP到Web服務器以前,仍然能夠嘗試一些操做。

您能夠檢查GIF並查看它們是否使用與圖像中顏色數對應的調色板大小。使用imagemagick很容易檢查
identify -verbose image.gif
當你在調色板中看到使用4種顏色和256色「槽」的圖像時,還有改進的餘地。
嘗試將GIF轉換爲PNG並查看是否存在保存。一般,有。因爲瀏覽器的支持有限,開發人員常常對使用PNG猶豫不決,但如今已成爲過去。惟一真正的問題是真彩色PNG中的alpha透明度,可是GIF也不是真彩色,也不支持變量透明度。因此GIF能夠作任何事情,調色板PNG(PNG8)也能夠作(動畫除外)。這個簡單的imagemagick命令致使徹底安全的PNG:
convert image.gif image.png
「咱們所說的只是:給PiNG一個機會!」
在全部PNG上 運行pngcrush(或任何其餘PNG優化工具)。例:
pngcrush image.png -rem alla -reduce -brute result.png
在全部JPEG上運行jpegtran。此工具執行無損JPEG操做(如旋轉),還可用於優化和刪除圖像中的註釋和其餘無用信息(如EXIF信息)。
jpegtran -copy none -optimize -perfect src.jpg dest.jpg
最佳

優化CSS Sprites tag: images

將圖像水平排列在精靈中而不是垂直排列一般會致使文件較小。
在精靈中組合類似的顏色能夠幫助您保持較低的顏色數,理想狀況下在256色如下,以適應PNG8。
「適合移動設備」而且不要在精靈中留下大的間隙。這不會影響文件大小,但須要較少的內存,以便用戶代理將圖像解壓縮爲像素圖。100x100圖像是1萬像素,其中1000x1000是100萬像素
最佳

不要在HTML中縮放圖像 tag: images

不要使用比您須要的更大的圖像,由於您能夠在HTML中設置寬度和高度。若是您須要,
<img width="100" height="100" src="mycat.jpg" alt="My Cat" />
那麼您的圖像(mycat.jpg)應該是100x100px而不是縮小的500x500px圖像。

最佳

make favicon.ico Small and Cacheable tag: images

favicon.ico是一個保留在服務器根目錄中的映像。這是一個必要的邪惡,由於即便你不關心它,瀏覽器仍然會請求它,因此最好不要回復404 Not Found。此外,因爲它位於同一臺服務器上,所以每次請求時都會發送cookie。此圖像也會干擾下載順序,例如在IE中,當您在onload中請求額外組件時,將在這些額外組件以前下載favicon。

所以,爲了減輕擁有favicon.ico的缺點,請確保:

它很小,最好不到1K。
使用您感受溫馨的設置Expires標頭(由於若是您決定更改它,則沒法重命名)。您能夠在未來幾個月安全地設置Expires標頭。您能夠查看當前favicon.ico的上次修改日期,以作出明智的決定。
Imagemagick能夠幫助您建立小的favicons

保持組件低於25K tag: mobile

此限制與iPhone不會緩存大於25K的組件這一事實有關。請注意,這是未壓縮的大小。這是縮小很重要的地方,由於單獨使用gzip可能還不夠。

欲瞭解更多信息,請查看Wayne Shea和Tenni Theurer的「 性能研究,第5部分:iPhone可緩存性 - 讓它堅持下去 」。

將組件打包到多部分文檔中 tag: mobile

將組件打包到多部分文檔就像帶有附件的電子郵件,它能夠幫助您經過一個HTTP請求獲取多個組件(請記住:HTTP請求很昂貴)。使用此技術時,首先檢查用戶代理是否支持它(iPhone不支持)。

避免空圖像src tag: server

帶有空字符串src屬性的圖像會出現多個預期。它以兩種形式出現:

HTML
<img src =「」>
JavaScript
var img = new Image();
img.src =「」;
兩種形式都會產生相同的效果:瀏覽器向您的服務器發出另外一個請求

Internet Explorer向頁面所在的目錄發出請求。
Safari和Chrome會向實際頁面提出請求。
Firefox 3及更早版本的行爲與Safari和Chrome相同,但3.5版解決了此問題[錯誤444931],再也不發送請求。
遇到空圖像時,Opera不執行任何操做。

爲何這種行爲很差?

經過發送大量意外流量來削弱您的服務器,特別是對於天天得到數百萬頁面瀏覽量的頁面。
廢棄服務器計算週期生成永遠不會被查看的頁面。
可能會損壞用戶數據。若是您經過cookie或其餘方式跟蹤請求中的狀態,則可能會破壞數據。即便圖像請求未返回圖像,瀏覽器也會讀取並接受全部標頭,包括全部cookie。雖然其他的響應被丟棄,但可能已經形成了損害。

此行爲的根本緣由是在瀏覽器中執行URI解析的方式。此行爲在RFC 3986 - 統一資源標識符中定義。當遇到空字符串做爲URI時,它被視爲相對URI,並根據5.2節中定義的算法進行解析。這個具體的例子是一個空字符串,在5.4節中列出。Firefox,Safari和Chrome都按照規範正確解析空字符串,而Internet Explorer正在解析它,顯然符合規範的早期版本RFC 2396 - 統一資源標識符(這已被RFC 3986廢棄) 。從技術上講,瀏覽器正在作他們應該作的事情來解析相對URI。問題是在這種狀況下,

HTML5添加了標記的src屬性的描述,以指示瀏覽器不要在4.8.2節中提出額外的請求:

src屬性必須存在,而且必須包含引用非交互式(可選動畫)圖像資源的有效URL,該資源既不是分頁也不是腳本。若是元素的基URI與文檔的地址相同,則src屬性的值不能是空字符串。
但願瀏覽器未來不會出現這個問題。不幸的是,<script src =「」>和<link href =「」>沒有這樣的子句。也許還有時間進行調整以確保瀏覽器不會意外地實現此行爲。
這條規則的靈感來自雅虎的JavaScript大師Nicolas C. Zakas。有關更多信息,請查看他的文章「 空圖像src能夠破壞您的網站 」。

原文地址:https://developer.yahoo.com/p...

相關文章
相關標籤/搜索