最新博客站點:歡迎來訪javascript
1. 最小化HTTP請求次數php
最終用戶響應時間的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%使用空緩存。讓這些首次訪問者快速訪問頁面是得到更好用戶體驗的關鍵。數據庫
2. 使用內容分發網絡(CDN)express
用戶與Web服務器的距離會對響應時間產生影響。在多個地理位置分散的服務器上部署內容將使您的頁面從用戶的角度加載更快。可是你應該從哪裏開始呢?
做爲實現地理位置分散的內容的第一步,請勿嘗試從新設計Web應用程序以在分佈式體系結構中工做。根據應用程序的不一樣,更改體系結構可能包括使人生畏的任務,例如同步會話狀態和跨服務器位置複製數據庫事務。嘗試縮短用戶與您的內容之間的距離可能會延遲或永遠不會經過此應用程序架構步驟。
請記住,最終用戶響應時間的80-90%用於下載頁面中的全部組件:圖像,樣式表,腳本,Flash等。這是性能黃金規則。而不是從從新設計應用程序架構的艱鉅任務開始,最好先分散靜態內容。這不只能夠縮短響應時間,並且因爲內容交付網絡,它更容易實現。
內容傳送網絡(CDN)是分佈在多個位置的Web服務器的集合,以更有效地向用戶傳送內容。選擇用於向特定用戶傳送內容的服務器一般基於網絡鄰近度的度量。例如,選擇具備最少網絡跳躍的服務器或具備最快響應時間的服務器。
一些大型互聯網公司擁有本身的CDN,但使用CDN服務提供商(如Akamai Technologies,EdgeCast或level3)具備成本效益。對於初創公司和私人網站來講,CDN服務的成本可能太高,但隨着您的目標受衆變得愈來愈大並變得更加全球化,CDN對於實現快速響應時間是必要的。在Yahoo!中,將靜態內容從其應用程序Web服務器移動到CDN(如上所述的第三方以及Yahoo本身的CDN)的屬性將最終用戶響應時間提升了20%或更多。切換到CDN是一個相對容易的代碼更改,將顯著提升您的網站的速度。
3. 添加Expires或Cache-Control標頭
這條規則有兩個方面:
Expires
標頭實現「永不過時」策略Cache-Control
標頭來幫助瀏覽器處理條件請求網頁設計愈來愈豐富,這意味着頁面中有更多的腳本,樣式表,圖像和Flash。您的頁面的首次訪問者可能必須發出多個HTTP請求,但經過使用Expires標頭,您可使這些組件可緩存。這能夠避免後續頁面查看中沒必要要的HTTP請求。Expires頭文件一般與圖像一塊兒使用,但它們應該用於全部組件,包括腳本,樣式表和Flash組件。
瀏覽器(和代理)使用緩存來減小HTTP請求的數量和大小,從而加快網頁加載速度。Web服務器使用HTTP響應中的Expires頭來告訴客戶端能夠緩存組件多長時間。這是一個遙遠的將來Expires標題,告訴瀏覽器這個響應在2010年4月15日以前不會過期。
Expires: Thu, 15 Apr 2010 20:00:00 GMT
若是您的服務器是Apache,請使用ExpiresDefault指令設置相對於當前日期的到期日期。ExpiresDefault指令的這個示例將Expires日期設置爲距請求時間10年。
ExpiresDefault "access plus 10 years"
請記住,若是您使用遠期的Expires標頭,則必須在組件更改時更改組件的文件名。在Yahoo! 咱們常常將此步驟做爲構建過程的一部分:版本號嵌入在組件的文件名中,例如,yahoo_2.0.6.js。
使用遠期Expires標頭僅在用戶訪問過您的網站後纔會影響網頁瀏覽量。當用戶第一次訪問您的站點而且瀏覽器的緩存爲空時,它對HTTP請求的數量沒有影響。所以,此性能改進的影響取決於用戶使用已準備好的緩存命中您的頁面的頻率。(「已準備好的緩存」已包含頁面中的全部組件。)咱們在Yahoo!上測量了這一點。並發現帶有固定緩存的頁面查看次數爲75-85%。經過使用遠期的Expires標頭,您能夠增長瀏覽器緩存的組件數量,並在後續頁面視圖中重複使用,而無需經過用戶的Internet鏈接發送單個字節。
4. 使用Gzip組件
經過前端工程師作出的決策,能夠顯着減小在網絡上傳輸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標準化。您可能會看到的惟一其餘壓縮格式是deflate,但效果較差且不太受歡迎。
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,並且可能會增長文件大小。
儘量多地壓縮文件類型是減輕頁面重量和加速用戶體驗的簡便方法。
5. 將CSS樣式表放在頂部
在研究Yahoo!的性能時,咱們發現將樣式表移動到文檔HEAD會使頁面看起來加載速度更快。這是由於將樣式表放在HEAD中容許頁面逐步呈現。
關注性能的前端工程師但願頁面逐步加載; 也就是說,咱們但願瀏覽器儘快顯示它擁有的任何內容。這對於具備大量內容的頁面和對較慢Internet鏈接的用戶尤爲重要。爲用戶提供視覺反饋(例如進度指示器)的重要性已獲得很好的研究和記錄。在咱們的例子中,HTML頁面是進度指示器!當瀏覽器逐步加載頁面時,標題,導航欄,頂部的徽標等都做爲等待頁面的用戶的視覺反饋。這改善了總體用戶體驗。
將樣式表放在文檔底部附近的問題是它禁止在許多瀏覽器(包括Internet Explorer)中逐行渲染。這些瀏覽器會阻止渲染,以免在樣式發生變化時重繪頁面元素。用戶查看空白頁面時卡住了。
HTML規範明確指出,樣式表是被包括在網頁的HEAD:「與A,[LINK]能夠僅出如今一個文檔的HEAD部分,儘管它可能出現任意次數」。這些替代品,空白的白色屏幕或無風格內容的閃光都是值得冒險的。最佳解決方案是遵循HTML規範並在文檔HEAD中加載樣式表。
6. 將JavaScript腳本放在底部
腳本引發的問題是它們阻止了並行下載。HTTP / 1.1規範建議的瀏覽器下載不超過兩種組分在每主機名平行。若是您從多個主機名提供圖像,則能夠並行執行兩次以上的下載。可是,在下載腳本時,即便在不一樣的主機名上,瀏覽器也不會啓動任何其餘下載。
在某些狀況下,將腳本移到底部並不容易。例如,若是腳本用於document.write
插入頁面內容的一部分,則沒法在頁面中向下移動。可能還存在範圍問題。在許多狀況下,有辦法解決這些問題。
常常出現的另外一種建議是使用延遲腳本。該DEFER
屬性代表該腳本不包含document.write,而且是瀏覽器能夠繼續呈現的線索。不幸的是,Firefox不支持該DEFER
屬性。在Internet Explorer中,腳本可能會延遲,但不是所需的。若是能夠延遲腳本,也能夠將其移動到頁面底部。這將使您的網頁加載速度更快。
7. 避免使用CSS中的expressions
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表達式,請記住它們可能會被評估數千次,並可能影響頁面的性能。
8. 將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,但在頁面加載完成後動態下載外部文件。後續頁面將引用應該已存在於瀏覽器緩存中的外部文件。
9. 減小DNS查詢
域名系統(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查找和容許高度並行下載之間的良好折衷。
10. 壓縮JavaScript和CSS(包括內聯<script>和<style>)
壓縮是從代碼中刪除沒必要要的字符以減少其大小從而改善加載時間的作法。壓縮代碼時,將刪除全部註釋,以及不須要的空格字符(空格,換行符和製表符)。在JavaScript的狀況下,這改善了響應時間性能,由於下載文件的大小減少了。用於壓縮JavaScript代碼的兩種流行工具是JSMin和YUI Compressor。YUI壓縮器也能夠壓縮CSS。
混淆是能夠應用於源代碼的替代優化。它比壓縮更復雜,所以更容易因混淆步驟自己而產生錯誤。在對美國十大頂級網站的調查中,壓縮規模縮小了21%,而混淆縮小了25%。儘管混淆具備更高的大小縮減,但壓縮JavaScript的風險較小。
除了壓縮外部腳本和樣式以外,內聯<script>
和<style>
塊也能夠而且也應該壓縮。即便你gzip你的腳本和樣式,壓縮它們仍然會減少5%或更多的大小。隨着JavaScript和CSS的使用和大小的增長,壓縮代碼所節省的成本也會增長。
11. 避免重定向
使用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/astrology會產生301響應,其中包含重定向到http://astrology.yahoo.com/astrology/(注意添加的尾部斜槓)。若是您使用的是Apache處理程序,則能夠使用Alias 或
mod_rewrite 或
DirectorySlash
指令在Apache中修復此問題。
將舊網站鏈接到新網站是重定向的另外一種常見用途。其餘包括鏈接網站的不一樣部分並基於特定條件(瀏覽器類型,用戶賬戶類型等)指導用戶。使用重定向鏈接兩個網站很簡單,只須要不多的額外編碼。雖然在這些狀況下使用重定向會下降開發人員的複雜性,但會下降用戶體驗。使用重定向的替代方法包括使用Alias
以及mod_rewrite
兩個代碼路徑是否託管在同一服務器上。若是域名更改是使用重定向的緣由,則另外一種方法是建立CNAME(建立從一個域名指向另外一個域名的別名的DNS記錄)與Alias
或組合mod_rewrite
。
12. 刪除重複的腳本
在一個頁面中兩次包含相同的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頭。
13. 配置實體標記ETag
實體標記(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。
ChangeNumber
是用於跟蹤IIS配置更改的計數器。後面整個網站的全部IIS服務器ChangeNumber
是相同這是不太可能的。
最終結果是Apache和IIS生成的ETag對於徹底相同的組件從一臺服務器到另外一臺服務器不匹配。若是ETag不匹配,則用戶不會收到ETag設計的小的,快速的304響應; 相反,他們將得到正常的200響應以及組件的全部數據。若是您只在一臺服務器上託管您的網站,這不是問題。可是,若是您有多個服務器託管您的網站,而且您正在使用具備默認ETag配置的Apache或IIS,則您的用戶正在變慢頁面,您的服務器負載更高,您正在消耗更大的帶寬,而且代理服務器沒有有效地緩存您的內容。即便您的組件具備遠期Expires
標頭,每當用戶點擊從新加載或刷新時,仍會發出條件GET請求。
若是您沒有利用ETag提供的靈活驗證模型,最好只刪除ETag。該Last-Modified
頭驗證基於對組件的時間戳。刪除ETag會減小響應和後續請求中HTTP標頭的大小。此Microsoft支持文章介紹瞭如何刪除ETag。在Apache中,只需將如下行添加到Apache配置文件便可:
FileETag none
14. 使Ajax能夠緩存
Ajax的一個優勢是它爲用戶提供即時反饋,由於它從後端Web服務器異步請求信息。可是,使用Ajax並不能保證用戶不會在等待那些異步JavaScript和XML響應返回時大拇指。在許多應用程序中,用戶是否保持等待取決於Ajax的使用方式。例如,在基於Web的電子郵件客戶端中,用戶將一直等待Ajax請求的結果,以查找符合其搜索條件的全部電子郵件。重要的是要記住「異步」並不意味着「瞬時」。
爲了提升性能,優化這些Ajax響應很是重要。提升Ajax性能的最重要方法是使響應可緩存,如添加Expires或Cache-controll標頭中所述。其餘一些規則也適用於Ajax:
咱們來看一個例子。Web 2.0電子郵件客戶端可能使用Ajax下載用戶的通信簿以進行自動完成。若是用戶自上次使用電子郵件Web應用程序以來未修改過她的地址簿,則能夠從緩存中讀取先前的地址簿響應,若是該Ajax響應可使用未來的Expires或Cache-Control標頭進行緩存。必須通知瀏覽器什麼時候使用先前緩存的地址簿響應而不是請求新的地址簿響應。這能夠經過向地址簿Ajax URL添加時間戳來完成,該時間戳指示用戶上次修改其地址簿的時間,例如,&t=1190241612
。若是自上次下載後地址簿還沒有被修改,則時間戳將相同,而且將從瀏覽器的緩存中讀取地址簿,從而消除額外的HTTP往返。若是用戶修改了地址簿,則時間戳確保新URL與緩存的響應不匹配,瀏覽器將請求更新的地址簿條目。
即便您的Ajax響應是動態建立的,而且可能僅適用於單個用戶,它們仍然能夠緩存。這樣作可使您的Web 2.0應用程序更快。
15. 儘早清除緩衝區
當用戶請求頁面時,後端服務器可能須要200到500毫秒才能將HTML頁面拼接在一塊兒。在此期間,瀏覽器在等待數據到達時處於空閒狀態。在PHP中,您有函數flush()。它容許您將部分準備好的HTML響應發送到瀏覽器,以便瀏覽器能夠在後端忙於HTML頁面的其他部分時開始獲取組件。這種好處主要出如今繁忙的後端或輕量級前端。
考慮刷新的好地方就在HEAD以後,由於頭部的HTML一般更容易生成,而且它容許您包含任何CSS和JavaScript文件,以便瀏覽器在後端處理時並行地開始獲取。
例:
... <!-- css, js --> </head> <?php flush(); ?> <body> ... <!-- content -->
雅虎 搜索開創性研究和真實用戶測試,以證實使用此技術的好處。
16. 使用GET進行Ajax請求
在雅虎 郵件團隊發現,在使用時XMLHttpRequest
,POST在瀏覽器中實現爲兩步過程:首先發送標頭,而後發送數據。所以最好使用GET,它只須要一個TCP數據包發送(除非你有不少cookie)。IE中的最大URL長度爲2K,所以若是發送的數據超過2K,則可能沒法使用GET。
一個有趣的反作用是沒有實際發佈任何數據的POST就像GET同樣。根據HTTP規範,GET用於檢索信息,所以當您僅請求數據時,使用GET是有意義的(語義上),而不是將數據發送到服務器端存儲。
17. 延遲加載組件
您能夠仔細查看您的頁面並問本身:「頁面最初渲染必要的是什麼?」。其他的內容和組件能夠等待。
JavaScript是在onload事件以前和以後拆分的理想候選者。例如,若是您有執行拖放和動畫的JavaScript代碼和庫,則能夠等待,由於在初始渲染以後拖動頁面上的元素。其餘尋找後期加載候選者的地方包括隱藏內容(用戶操做後顯示的內容)和首屏下方的圖像。
幫助您完成工做的工具:YUI Image Loader容許您將圖像延遲到摺疊下方,YUI Get實用程序是一種簡單的方法,能夠動態地包含JS和CSS。在野外的例子看看雅虎!打開Firebug網絡面板的主頁。
當性能目標與其餘Web開發最佳實踐一致時,這是很好的。在這種狀況下,漸進加強的想法告訴咱們,JavaScript在受支持時能夠改善用戶體驗,但您必須確保即便沒有JavaScript也能正常工做。所以,在確保頁面正常工做以後,您可使用一些後期加載的腳原本加強它,這些腳本能夠爲您提供更多的花俏功能,例如拖放和動畫。
18. 預加載組件
預加載可能看起來與延遲加載相反,但它實際上有不一樣的目標。經過預加載組件,您能夠利用瀏覽器空閒的時間並請求未來須要的組件(如圖像,樣式和腳本)。這樣,當用戶訪問下一頁時,您能夠將大部分組件放在緩存中,而且您的頁面將爲用戶加載更快。
實際上有幾種類型的預加載:
19. 減小DOM元素的數量
複雜頁面意味着要下載更多字節,這也意味着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標記)。
20. 跨域拆分組件
拆分組件容許您最大化並行下載。因爲DNS查詢懲罰,請確保您使用的域名不超過2-4個。例如,您能夠託管HTML和動態內容,www.example.org
並在static1.example.org
和之間拆分靜態組件static2.example.org
有關更多信息,請查看Tenni Theurer和Patty Chi的「 在Carpool Lane中最大化並行下載 」。
21. 最小化iframe數量
iframe容許將HTML文檔插入父文檔中。瞭解iframe如何運做以便有效使用很是重要。
<iframe>
優勢:
<iframe>
缺點:
22. 不用404s
HTTP請求很昂貴,所以發出HTTP請求並得到無用的響應(即404 Not Found)是徹底不必的,而且會在沒有任何好處的狀況下減慢用戶體驗。
有些網站有幫助404「你的意思是X?」,這對用戶體驗頗有好處,但也浪費了服務器資源(好比數據庫等)。特別糟糕的是當外部JavaScript的連接錯誤而且結果是404時。首先,此下載將阻止並行下載。接下來,瀏覽器可能會嘗試解析404響應主體,就像它是JavaScript代碼同樣,試圖找到可用的東西。
23. 減少Cookie大小
HTTP cookie的使用有多種緣由,例如身份驗證和個性化。有關cookie的信息在Web服務器和瀏覽器之間的HTTP標頭中進行交換。保持cookie的大小盡量低是很是重要的,以儘可能減小對用戶響應時間的影響。
欲瞭解更多信息,請查看 Tenni Theurer和Patty Chi撰寫的「當Cookie崩潰時」。這項研究的主要內容:
24. 對組建使用cookie-free的域名
當瀏覽器發出靜態圖像請求並將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寫入該子域。
25. 最小化DOM的訪問次數
使用JavaScript訪問DOM元素的速度很慢,所以爲了得到響應更快的頁面,您應該:
有關更多信息,請查看 Julien Lecomte 的YUI影院的 「高性能Ajax應用程序」。
26. 開發巧妙的事件處理程序
有時頁面感受響應性較差,由於過多的事件處理程序附加到DOM樹的不一樣元素,而後執行得太頻繁。這就是爲何使用事件委託是一個很好的方法。若是a中有10個按鈕div
,則只將一個事件處理程序附加到div包裝器,而不是每一個按鈕一個處理程序。事件冒出來,這樣你就能夠捕捉事件並找出它來自哪一個按鈕。
您也不須要等待onload事件以便開始使用DOM樹執行某些操做。一般,您只須要在樹中訪問要訪問的元素。您沒必要等待下載全部圖像。DOMContentLoaded
是您可能考慮使用的事件而不是onload,但在全部瀏覽器中均可用以前,您可使用具備方法的YUI事件實用程序onAvailable
。
有關更多信息,請查看 Julien Lecomte 的YUI影院的 「高性能Ajax應用程序」。
27. 優先選擇使用<link>而非@import
以前的最佳實踐之一聲明CSS應位於頂部以容許漸進式渲染。
在IE中,@import
行爲與<link>
在頁面底部使用相同,所以最好不要使用它。
28. 避免使用filters
IE專有的AlphaImageLoader
過濾器旨在解決IE版本<7中的半透明真彩色PNG的問題。該過濾器的問題在於它在下載圖像時阻止渲染並凍結瀏覽器。它還會增長內存消耗,而且每一個元素應用,而不是每一個圖像,所以問題成倍增長。
最好的方法是AlphaImageLoader
徹底避免使用優雅降級的PNG8,這在IE中很好。若是你絕對須要AlphaImageLoader
,使用下劃線黑客_filter
不會懲罰你的IE7 +用戶。
29. 優化圖片
設計師完成爲您的網頁建立圖像後,在將這些圖像FTP到Web服務器以前,仍然能夠嘗試一些操做。
identify -verbose image.gif
convert image.gif image.png
pngcrush image.png -rem alla -reduce -brute result.png
jpegtran -copy none -optimize -perfect src.jpg dest.jpg
30.優化CSS Sprites
31. 不要在HTML中縮放圖像
不要使用比您須要的更大的圖像,由於您能夠在HTML中設置寬度和高度。若是您須要,
<img width="100" height="100" src="mycat.jpg" alt="My Cat" />
那麼您的圖像(mycat.jpg)應該是100x100px而不是縮小的500x500px圖像。
32. 減少favicon.ico的體積並緩存
favicon.ico是一個保留在服務器根目錄中的映像。這是一個必要的邪惡,由於即便你不關心它,瀏覽器仍然會請求它,因此最好不要回復404 Not Found
。此外,因爲它位於同一臺服務器上,所以每次請求時都會發送cookie。此圖像也會干擾下載順序,例如在IE中,當您在onload中請求額外組件時,將在這些額外組件以前下載favicon。
所以,爲了減輕擁有favicon.ico的缺點,請確保:
Imagemagick能夠幫助您建立小的favicons
33. 保持組件小於25K
此限制與iPhone不會緩存大於25K的組件這一事實有關。請注意,這是未壓縮的大小。這是縮小很重要的地方,由於單獨使用gzip可能還不夠。
欲瞭解更多信息,請查看Wayne Shea和Tenni Theurer的「 性能研究,第5部分:iPhone可緩存性 - 讓它堅持下去 」。
34. 將組件拆分到多個文檔中
將組件打包到多部分文檔就像帶有附件的電子郵件,它能夠幫助您經過一個HTTP請求獲取多個組件(請記住:HTTP請求很昂貴)。使用此技術時,首先檢查用戶代理是否支持它(iPhone不支持)。
35. 避免設置空圖像的src
帶有空字符串src屬性的圖像會出現多個預期。它以兩種形式出現:
<img src =「」>
var img = new Image();
img.src =「」;
兩種形式都會產生相同的效果:瀏覽器向您的服務器發出另外一個請求
爲何這種行爲很差?
此行爲的根本緣由是在瀏覽器中執行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。有關更多信息,請查看他的文章「 Empty image src can destroy your site 」。
英文連接: