雅虎35條優(yōu)化黃金守則
Excetional Performance 團(tuán)隊(duì)總結(jié)出了一系列可以提高網(wǎng)站速度的方法。可以分為 7大類 35條。
包括內(nèi)容 、服務(wù)器 、 CSS 、 JavaScript 、Cookie 、圖片 、移動(dòng)應(yīng)用 ,七部分。?
一、內(nèi)容部分
- 盡量減少 HTTP請求
- 減少 DNS查找
- 避免跳轉(zhuǎn)
- 緩存 Ajxa
- 推遲加載
- 提前加載
- 減少 DOM元素?cái)?shù)量
- 用域名劃分頁面內(nèi)容
- 使 frame數(shù)量最少
- 避免 404錯(cuò)誤
?
1、盡量減少 HTTP請求次數(shù)
? ?? ? 終端用戶響應(yīng)的時(shí)間中,有 80%用于下載各項(xiàng)內(nèi)容。這部分時(shí)間包括下載頁面中的圖像、樣式表、腳本、 Flash等。通過減少頁面中的元素可以減少 HTTP請求的次數(shù)。這是提高網(wǎng)頁速度的關(guān)鍵步驟。
??減少頁面組件的方法其實(shí)就是簡化頁面設(shè)計(jì)。那么有沒有一種方法既能保持頁面內(nèi)容的豐富性又能達(dá)到加快響應(yīng)時(shí)間的目的呢?這里有幾條減少HTTP請求次數(shù)同時(shí)又可能保持頁面內(nèi)容豐富的技術(shù)。
?
合并文件是通過把所有的腳本放到一個(gè)文件中來減少 HTTP請求的方法,如可以簡單地把所有的 CSS文件都放入一個(gè)樣式表中。當(dāng)腳本或者樣式表在不同頁面中使用時(shí)需要做不同的修 改,這可能會相對麻煩點(diǎn),但即便如此也要把這個(gè)方法作為改善頁面性能的重要一步。
?
CSS Sprites是減少圖像請求的有效方法。把所有的背景圖像都放到一個(gè)圖片文件中,然后通過 CSS的 background-image和 background-position屬性來顯示圖片的不同部分;
?
圖 片地圖是把多張圖片整合到一張圖片中。雖然文件的總體大小不會改變,但是可 以減少 HTTP請求次數(shù)。圖片地圖只有在圖片的所有組成部分在頁面中是緊挨在一起的時(shí)候才能 使用,如導(dǎo)航欄。確定圖片的坐標(biāo)和可能會比較繁瑣且容易出錯(cuò),同時(shí)使用圖片地圖導(dǎo)航也不具有可讀性,因此不推薦這種方法;
?
內(nèi)聯(lián)圖像是使用 data:URL scheme的方法把圖像數(shù)據(jù)加載頁面中。這可能會增加頁面的大 小。把內(nèi)聯(lián)圖像放到樣式表(可緩存)中可以減少 HTTP請求同時(shí)又避免增加頁面文件的大小。但是內(nèi)聯(lián)圖像現(xiàn)在還沒有得到主流瀏覽器的 支持。
?
??減 少頁面的 HTTP請求次數(shù)是你首先要做的一步。這是改進(jìn)首次訪問用戶等待時(shí)間的最重要的方法。 如同 Tenni Theurer的他的博客 Browser Cahe Usage - Exposed!中所說, HTTP請求在無緩存情況下占去了 40%到 60%的響應(yīng)時(shí)間。讓那些初次訪問你網(wǎng)站的人獲得更加快速的體驗(yàn)吧!
?
2、減少 DNS查找次數(shù)
??域 名系統(tǒng)( DNS)提供了域名和 IP的對應(yīng)關(guān)系,就像電話本中人名和他們的電話號碼的關(guān)系一樣。當(dāng)你在瀏覽器地址欄中 輸入 www.yahoo.com 時(shí), DNS解析服務(wù)器就會返回這個(gè)域名對應(yīng)的 IP地址。 DNS解析的過程同樣也是需要時(shí)間的。一般情況下返回給定域名對應(yīng)的 IP地址會花費(fèi) 20到 120毫秒的時(shí)間。而且在這個(gè)過程中瀏覽器什么都不會做直到 DNS查找完畢。
?
? ?緩存 DNS查找可以改善頁面性能。這種緩存需要一個(gè)特定的緩存服務(wù)器,這種服務(wù)器一般屬于用戶的 ISP提供商或者本地局域網(wǎng)控制,但是它同樣會在用戶使用的計(jì)算機(jī)上產(chǎn)生緩存。 DNS信息會保留在操作系統(tǒng)的 DNS緩存中(微軟 Windows系統(tǒng)中 DNS Client Service)。大多數(shù)瀏覽器有獨(dú)立于操作系統(tǒng)以外的自己的緩存。由于瀏覽器有自己的緩存記錄,因此在一次請求中它不會受到操作系統(tǒng)的影響。
?
??Internet Explorer 默認(rèn)情況下對 DNS查找記錄的緩存時(shí)間為 30分鐘,它在注冊表中的鍵值為 DnsCacheTimeout。 Firefox對 DNS的查找記錄緩存時(shí)間為 1分鐘,它在配置文件中的選項(xiàng)為 network.dnsCacheExpiration( Fasterfox把這個(gè)選項(xiàng)改為了 1小時(shí))。
?
??當(dāng)客戶端中的 DNS緩存都為空時(shí)(瀏覽器和操作系統(tǒng)都為空), DNS查找的次數(shù)和頁面中主機(jī)名的數(shù)量相同。這其中包括頁面中 URL、圖片、腳本文件、樣式表、Flash對象等包含的主機(jī)名。減少主機(jī)名的數(shù)量可以減少DNS查找次數(shù)。
?
??減 少主機(jī)名的數(shù)量還可以減少頁面中并行下載的數(shù)量。減少 DNS查找次數(shù)可以節(jié)省響應(yīng)時(shí)間,但是減少并行下載卻會增加響應(yīng)時(shí)間。我的指導(dǎo)原則是 把這些頁面中的內(nèi)容分割成至少兩部分但不超過四部分。這種結(jié)果就是在減少 DNS查找次數(shù)和保持較高程度并行下載兩者之間的權(quán)衡了。
?
3、避免跳轉(zhuǎn)
跳轉(zhuǎn)是使用 301和 302代碼實(shí)現(xiàn)的。下面是一個(gè)響應(yīng)代碼為 301的 HTTP頭:
? ?? ?HTTP/1.1 301 Moved Permanently
? ?? ?Location:? http://example.com/newuri
? ?? ?Content-Type: text/html
??瀏 覽器會把用戶指向到 Location中指定的 URL。頭文件中的所有信息在一次跳轉(zhuǎn)中都是必需的,內(nèi)容部分可以為空。不管他們的名 稱, 301和 302響應(yīng)都不會被緩存除非增加一個(gè)額外的頭選項(xiàng),如 Expires或者 Cache-Control來指定它緩存。 <meat />元素的刷新標(biāo)簽和JavaScript也可以實(shí)現(xiàn) URL的跳轉(zhuǎn),但是如果你必須要跳轉(zhuǎn)的時(shí)候,最好的方法就是使用標(biāo)準(zhǔn)的 3XXHTTP狀態(tài)代碼,這主要是為了確保“后退”按鈕可以正確地使用。
?
??但是要記住跳轉(zhuǎn)會降低用戶體驗(yàn)。在用戶和 HTML文檔中間增加一個(gè)跳轉(zhuǎn),會拖延頁面中所有元素的顯示,因?yàn)樵?HTML文件被加載前任何文件(圖像、 Flash等)都不會被下載。
?
??有一種經(jīng)常被網(wǎng)頁開發(fā)者忽略卻往往十分浪費(fèi)響應(yīng)時(shí)間的跳轉(zhuǎn)現(xiàn)象。 這種現(xiàn)象發(fā)生在當(dāng) URL本該有斜杠( /)卻被忽略掉時(shí)。例如,當(dāng)我們要訪問? http://astrology.yahoo.com/astrology ?時(shí),實(shí)際上返回的是一個(gè)包含 301代碼的跳轉(zhuǎn),它指向的是? http://astrology.yahoo.com/astrology/ ??(注意末尾的斜杠)。在 Apache服務(wù)器中可以使用 Alias 或者 mod_rewrite或者 the DirectorySlash來避免。
?
??連 接新網(wǎng)站和舊網(wǎng)站是跳轉(zhuǎn)功能經(jīng)常被用到的另一種情況。這種情況 下往往要連接網(wǎng)站的不同內(nèi)容然后根據(jù)用戶的不同類型(如瀏覽器類型、用戶賬號所屬類型)來進(jìn)行跳轉(zhuǎn)。使用跳轉(zhuǎn)來實(shí)現(xiàn)兩個(gè)網(wǎng)站的切換十分簡單,需要的代碼量 也不多。盡管使用這種方法對于開發(fā)者來說可以降低復(fù)雜程度,但是它同樣降低用戶體驗(yàn)。一個(gè)可替代方法就是如果兩者在同一臺服務(wù)器上時(shí)使用 Alias和 mod_rewrite和實(shí)現(xiàn)。如果是因?yàn)橛蛎牟煌捎锰D(zhuǎn),那么可以通過使用 Alias或者 mod_rewirte建立 CNAME(保存一個(gè)域名和另外一個(gè)域名之間關(guān)系的DNS記錄)來替代。
?
4、可緩存的 AJAX
??Ajax 經(jīng)常被提及的一個(gè)好處就是由于其從后臺服務(wù)器傳輸信息 的異步性而為用戶帶來的反饋的即時(shí)性。但是,使用 Ajax并不能保證用戶不會在等待異步的 JavaScript和 XML響應(yīng)上花費(fèi)時(shí)間。在很多應(yīng)用中,用戶是否需要等待響應(yīng)取決于 Ajax如何來使用。例如,在一個(gè)基于 Web的 Email客戶端中,用戶必須等待 Ajax返回符合他們條件的郵件查詢結(jié)果。記住一點(diǎn),“異步”并不異味著“即時(shí)”,這 很重要。
?
??為了提高性能,優(yōu)化 Ajax響應(yīng)是很重要的。提高 Ajxa性能的措施中最重要的方法就是使響應(yīng)具有可緩存性,具體的討論可以查看 Add an Expires or a Cache-Control Header。 其它的幾條規(guī)則也同樣適用于Ajax:
? ? Gizp 壓縮文件
? ? 減少 DNS查找次數(shù)
? ? 精簡 JavaScript
? ? 避免跳轉(zhuǎn)
? ? 配置 ETags
?
??讓 我們來看一個(gè)例子:一個(gè) Web2.0的 Email客戶端會使用 Ajax來自動(dòng)完成對用戶地址薄的下載。如果用戶在上次使用過 Email web應(yīng)用程序后沒有對地址薄作任何的修改,而且 Ajax響應(yīng)通過 Expire或者 Cacke-Control頭來實(shí)現(xiàn)緩存,那么就可以直接從上一次的緩存中讀取地址薄 了。必須告知瀏覽器是使用緩存中的地址薄還是發(fā)送一個(gè)新的請求。這可以通過為讀取地址薄的 Ajax URL增加一個(gè)含有上次編輯時(shí)間的時(shí)間戳來實(shí)現(xiàn),例如, &t=11900241612等。如果地址薄在上次下載后沒有被編輯過,時(shí)間 戳就不變,則從瀏覽器的緩存中加載從而減少了一次 HTTP請求過程。如果用戶修改過地址薄,時(shí)間戳就會用來確定新的 URL和緩存響應(yīng)并不匹配,瀏覽器就會重要請求更新地址薄。
??即使你的 Ajxa響應(yīng)是動(dòng)態(tài)生成的,哪怕它只適用于一個(gè)用戶,那么它也應(yīng)該被緩存起來。這樣做 可以使你的 Web2.0應(yīng)用程序更加快捷。
?
5、推遲加載內(nèi)容
??你可以仔細(xì)看一下你的網(wǎng)頁,問問自己“哪些內(nèi)容是頁面呈現(xiàn)時(shí) 所必需首先加載的?哪些內(nèi)容和結(jié)構(gòu)可以稍后再加載?
??把 整個(gè)過程按照 onload事件分隔成兩部分, JavaScript是一個(gè)理想的選擇。例如,如果你有用于實(shí)現(xiàn)拖放和動(dòng)畫的 JavaScript,那么它就以等待稍后加載,因?yàn)轫撁嫔系耐戏旁厥窃诔跏蓟尸F(xiàn) 之后才發(fā)生的。其它的例如隱藏部分的內(nèi)容(用戶操作之后才顯現(xiàn)的內(nèi)容)和處于折疊部分的圖像也可以推遲加載
??工具可以節(jié)省你的工作量: YUI Image Loader可以幫你推遲加載折疊部分的圖片, YUI Get utility是包含 JS和 CSS的便捷方法。比如你可以打開 Firebug的 Net選項(xiàng)卡看一下 Yahoo的首頁。
??當(dāng) 性能目標(biāo)和其它網(wǎng)站開發(fā)實(shí)踐一致時(shí)就會相得益彰。這種情況 下,通過程序提高網(wǎng)站性能的方法告訴我們,在支持 JavaScript的情況下,可以先去除用戶體驗(yàn),不過這要保證你的網(wǎng)站在沒有 JavaScript也可以正常運(yùn)行。在確定頁面運(yùn)行正常后,再加載腳本來實(shí)現(xiàn)如拖放和動(dòng)畫等更加花哨的效果。
?
6、預(yù)加載
??預(yù) 加載和后加載看起來似乎恰恰相反,但實(shí)際上預(yù)加載是為了實(shí) 現(xiàn)另外一種目標(biāo)。預(yù)加載是在瀏覽器空閑時(shí)請求將來可能會用到的頁面內(nèi)容(如圖像、樣式表和腳本)。使用這種方法,當(dāng)用戶要訪問下一個(gè)頁面時(shí),頁面中的內(nèi)容 大部分已經(jīng)加載到緩存中了,因此可以大大改善訪問速度。
?
下面提供了幾種預(yù)加載方法:
??無 條件加載:觸發(fā) onload事件時(shí),直接加載額外的頁面內(nèi)容。以 Google.com為例,你可以看一下它的 spirit image圖像是怎樣在 onload中加載的。這個(gè) spirit image圖像在 google.com主頁中是不需要的,但是卻可以在搜索結(jié)果頁面中用到它。
有條件加載:根據(jù)用戶的操作來有根據(jù)地判斷用戶下面可能去往的頁面并相應(yīng)的預(yù) 加載頁面內(nèi)容。在 search.yahoo.com中你可以看到如何在你輸入內(nèi)容時(shí)加載額外的頁面內(nèi)容。
??有 預(yù)期的加載:載入重新設(shè)計(jì)過的頁面時(shí)使用預(yù)加載。這種情況經(jīng)常出現(xiàn)在頁面經(jīng)過重新設(shè)計(jì)后用戶抱怨“新的頁面看起來很酷,但是卻比以前慢”。問題可能出在 用戶對于你的舊站點(diǎn)建立了完整的緩存,而對于新站點(diǎn)卻沒有任何緩存內(nèi)容。因此你可以在訪問新站之前就加載一部內(nèi)容來避免這種結(jié)果的出現(xiàn)。在你的舊站中利用 瀏覽器的空余時(shí)間加載新站中用到的圖像的和腳本來提高訪問速度。
?
7、減少 DOM元素?cái)?shù)量
??一個(gè)復(fù)雜的頁面意味著需要下載更多數(shù)據(jù),同時(shí)也意味著 JavaScript遍歷 DOM的效率越慢。比如當(dāng)你增加一個(gè)事件句柄時(shí)在 500和 5000個(gè) DOM元素中循環(huán)效果肯定是不一樣的。
??大量的 DOM元素的存在意味著頁面中有可以不用移除內(nèi)容只需要替換元素標(biāo)簽就可以精簡的部分。你在頁面布局中使用表格了嗎?你有沒有僅僅為了布局而引入更多的 <div>元素呢?也許會存在一個(gè)適合或者在語意是更貼切的標(biāo)簽可以供你使用。
??YUI CSS utilities 可以給你的布局帶來巨大幫助: grids.css可以幫你實(shí)現(xiàn)整體布局, font.css和 reset.css可以幫助你移除瀏覽器默認(rèn)格式。它提供了一個(gè)重新審視你頁面中標(biāo)簽 的機(jī)會,比如只有在語意上有意義時(shí)才使用 <div>,而不是因?yàn)樗哂袚Q行效果才使用它。
??DOM 元素?cái)?shù)量很容易計(jì)算出來,只需要在 Firebug的控制臺內(nèi)輸入:
document.getElementsByTagName('*').length
??那么多少個(gè) DOM元素算是多呢?這可以對照有很好標(biāo)記使用的類似頁面。比如 Yahoo!主頁是一個(gè)內(nèi)容非常多的頁面,但是它只使用了 700個(gè)元素( HTML標(biāo)簽)。
?
8、根據(jù)域名劃分頁面內(nèi)容
??把頁面內(nèi)容劃分成若干部分可以使你最大限度地實(shí)現(xiàn)平行下載。由于 DNS查找?guī)淼挠绊懩闶紫纫_保你使用的域名數(shù)量在 2個(gè)到 4個(gè)之間。例如,你可以把用到的 HTML內(nèi)容和動(dòng)態(tài)內(nèi)容放在? http://www.example.org/ ?上,而把頁面各種組件(圖片、腳本、 CSS)分別存放在 statics1.example.org和 statics.example.org上。
你可在 Tenni Theurer和 Patty Chi合寫的文章 Maximizing Parallel Downloads in the Carpool Lane找到更多相關(guān)信息。
?
9、使 iframe的數(shù)量最小
??ifrmae 元素可以在父文檔中插入一個(gè)新的 HTML文檔。了解 iframe的工作理然后才能更加有效地使用它,這一點(diǎn)很重要。
?
<iframe>優(yōu)點(diǎn):
解決加載緩慢的第三方內(nèi)容如圖標(biāo)和廣告等的加載問題
Security sandbox
并行加載腳本
<iframe>的缺點(diǎn):
即時(shí)內(nèi)容為空,加載也需要時(shí)間
會阻止頁面加載
沒有語意
?
10、不要出現(xiàn) 404錯(cuò)誤
? ?HTTP 請求時(shí)間消耗是很大的,因此使用 HTTP請求來獲得一個(gè)沒有用處的響應(yīng)(例如 404沒有找到頁面)是完全沒有必要的,它只會降低用戶體驗(yàn)而不會有一點(diǎn)好處。
??有 些站點(diǎn)把 404錯(cuò)誤響應(yīng)頁面改為“你是不是要找 ***”,這雖然改進(jìn)了用戶體驗(yàn)但是同樣也會浪費(fèi)服務(wù)器資源(如數(shù)據(jù)庫等)。最糟糕的 情況是指向外部 JavaScript的鏈接出現(xiàn)問題并返回 404代碼。首先,這種加載會破壞并行加載;其次瀏覽器會把試圖在返回的404響應(yīng)內(nèi)容中找到可能有用的部分當(dāng)作 JavaScript代碼來執(zhí)行。
二、服務(wù)器部分
- 使用內(nèi)容分發(fā)網(wǎng)絡(luò)
- 為文件頭指定Expires或Cache-Control
- Gzip 壓縮文件內(nèi)容
- 配置ETag
- 盡早刷新輸出緩沖
- 使用GET來完成AJAX請求
- 避免空的圖像來源
?
11、使用內(nèi)容分發(fā)網(wǎng)絡(luò)
?
??用戶與你網(wǎng)站服務(wù)器的接近程度會影響響應(yīng)時(shí)間的長短。把你的網(wǎng)站內(nèi)容分散到多個(gè)、處于不同地域位置的服務(wù)器上可以加快下載速度。但是首先我們應(yīng)該做些什么呢?
??按地域布置網(wǎng)站內(nèi)容的第一步并不是要嘗試重新架構(gòu)你的網(wǎng)站讓他們在分發(fā)服務(wù)器上正常運(yùn)行。根據(jù)應(yīng)用的需求來改變網(wǎng)站結(jié)構(gòu),這可能會包括一些比較復(fù)雜的 任 務(wù),如在服務(wù)器間同步Session狀態(tài)和合并數(shù)據(jù)庫更新等。要想縮短用戶和內(nèi)容服務(wù)器的距離,這些架構(gòu)步驟可能是不可避免的。
??要記住,在終端用戶的響應(yīng)時(shí)間中有80%到90%的響應(yīng)時(shí)間用于下載圖像、樣式表、腳本、Flash等頁面內(nèi)容。這就是網(wǎng)站性能黃金守則。和重新設(shè)計(jì) 你的 應(yīng)用程序架構(gòu)這樣比較困難的任務(wù)相比,首先來分布靜態(tài)內(nèi)容會更好一點(diǎn)。這不僅會縮短響應(yīng)時(shí)間,而且對于內(nèi)容分發(fā)網(wǎng)絡(luò)來說它更容易實(shí)現(xiàn)。
??內(nèi)容分發(fā)網(wǎng)絡(luò)(Content Delivery Network,CDN)是由一系列分散到各個(gè)不同地理位置上的Web服務(wù)器組成的,它提高了網(wǎng)站內(nèi)容的傳輸速度。用于向用戶傳輸內(nèi)容的服務(wù)器主要是根據(jù) 和用戶在網(wǎng)絡(luò)上的靠近程度來指定的。例如,擁有最少網(wǎng)絡(luò)跳數(shù)(network hops)和響應(yīng)速度最快的服務(wù)器會被選定。
??一些大型的網(wǎng)絡(luò)公司擁有自己的CDN,但是使用像Akamai Technologies,Mirror Image Internet,或者Limelight Networks這樣的CDN服務(wù)成本卻非常高。對于剛剛起步的企業(yè)和個(gè)人網(wǎng)站來說,可能沒有使用CDN的成本預(yù)算,但是隨著目標(biāo)用戶群的不斷擴(kuò)大和更加 全球化,CDN就是實(shí)現(xiàn)快速響應(yīng)所必需的了。以Yahoo來說,他們轉(zhuǎn)移到CDN上的網(wǎng)站程序靜態(tài)內(nèi)容節(jié)省了終端用戶20%以上的響應(yīng)時(shí)間。使用CDN是 一個(gè)只需要相對簡單地修改代碼實(shí)現(xiàn)顯著改善網(wǎng)站訪問速度的方法。
?
12、為文件頭指定Expires或Cache-Control?
??這條守則包括兩方面的內(nèi)容:
對于靜態(tài)內(nèi)容:設(shè)置文件頭過期時(shí)間Expires的值為“Never expire”(永不過期)
對于動(dòng)態(tài)內(nèi)容:使用恰當(dāng)?shù)腃ache-Control文件頭來幫助瀏覽器進(jìn)行有條件的請求
??網(wǎng)頁內(nèi)容設(shè)計(jì)現(xiàn)在越來越豐富,這就意味著頁面中要包含更多的腳本、樣式表、圖片和Flash。第一次訪問你頁面的用戶就意味著進(jìn)行多次的HTTP請 求,但 是通過使用Expires文件頭就可以使這樣內(nèi)容具有緩存性。它避免了接下來的頁面訪問中不必要的HTTP請求。Expires文件頭經(jīng)常用于圖像文件, 但是應(yīng)該在所有的內(nèi)容都使用他,包括腳本、樣式表和Flash等。
??瀏覽器(和代理)使用緩存來減少HTTP請求的大小和次數(shù)以加快頁面訪問速度。Web服務(wù)器在HTTP響應(yīng)中使用Expires文件頭來告訴客戶端內(nèi) 容需 要緩存多長時(shí)間。下面這個(gè)例子是一個(gè)較長時(shí)間的Expires文件頭,它告訴瀏覽器這個(gè)響應(yīng)直到2010年4月15日才過期。
? ?? ?Expires: Thu, 15 Apr 2010 20:00:00 GMT?
??如果你使用的是Apache服務(wù)器,可以使用ExpiresDefault來設(shè)定相對當(dāng)前日期的過期時(shí)間。下面這個(gè)例子是使用ExpiresDefault來設(shè)定請求時(shí)間后10年過期的文件頭:
? ?? ?ExpiresDefault "access plus 10 years"?
??要切記,如果使用了Expires文件頭,當(dāng)頁面內(nèi)容改變時(shí)就必須改變內(nèi)容的文件名。依Yahoo!來說我們經(jīng)常使用這樣的步驟:在內(nèi)容的文件名中加上版 本號,如yahoo_2.0.6.js。
??使用Expires文件頭只有會在用戶已經(jīng)訪問過你的網(wǎng)站后才會起作用。當(dāng)用戶首次訪問你的網(wǎng)站時(shí)這對減少HTTP請求次數(shù)來說是無效的,因?yàn)闉g覽器 的緩 存是空的。因此這種方法對于你網(wǎng)站性能的改進(jìn)情況要依據(jù)他們“預(yù)緩存”存在時(shí)對你頁面的點(diǎn)擊頻率(“預(yù)緩存”中已經(jīng)包含了頁面中的所有內(nèi)容)。 Yahoo!建立了一套測量方法,我們發(fā)現(xiàn)所有的頁面瀏覽量中有75~85%都有“預(yù)緩存”。通過使用Expires文件頭,增加了緩存在瀏覽器中內(nèi)容的 數(shù)量,并且可以在用戶接下來的請求中再次使用這些內(nèi)容,這甚至都不需要通過用戶發(fā)送一個(gè)字節(jié)的請求。
?
13、Gzip壓縮文件內(nèi)容
?
??網(wǎng)絡(luò)傳輸中的HTTP請求和應(yīng)答時(shí)間可以通過前端機(jī)制得到顯著改善。的確,終端用戶的帶寬、互聯(lián)網(wǎng)提供者、與對等交換點(diǎn)的靠近程度等都不是網(wǎng)站開發(fā)者所能 決定的。但是還有其他因素影響著響應(yīng)時(shí)間。通過減小HTTP響應(yīng)的大小可以節(jié)省HTTP響應(yīng)時(shí)間。
??從HTTP/1.1開始,web客戶端都默認(rèn)支持HTTP請求中有Accept-Encoding文件頭的壓縮格式:? ?
? ?? ?Accept-Encoding: gzip, deflate?
??如果web服務(wù)器在請求的文件頭中檢測到上面的代碼,就會以客戶端列出的方式壓縮響應(yīng)內(nèi)容。Web服務(wù)器把壓縮方式通過響應(yīng)文件頭中的Content- Encoding來返回給瀏覽器。
? ?? ?Content-Encoding: gzip?
??Gzip是目前最流行也是最有效的壓縮方式。這是由GNU項(xiàng)目開發(fā)并通過RFC 1952來標(biāo)準(zhǔn)化的。另外僅有的一個(gè)壓縮格式是deflate,但是它的使用范圍有限效果也稍稍遜色。
??Gzip大概可以減少70%的響應(yīng)規(guī)模。目前大約有90%通過瀏覽器傳輸?shù)幕ヂ?lián)網(wǎng)交換支持gzip格式。如果你使用的是Apache,gzip模塊配置和 你的版本有關(guān):Apache 1.3使用mod_zip,而Apache 2.x使用moflate。
??瀏覽器和代理都會存在這樣的問題:瀏覽器期望收到的和實(shí)際接收到的內(nèi)容會存在不匹配的現(xiàn)象。幸好,這種特殊情況隨著舊式瀏覽器使用量的減少在減少。 Apache模塊會通過自動(dòng)添加適當(dāng)?shù)腣ary響應(yīng)文件頭來避免這種狀況的出現(xiàn)。
??服務(wù)器根據(jù)文件類型來選擇需要進(jìn)行g(shù)zip壓縮的文件,但是這過于限制了可壓縮的文件。大多數(shù)web服務(wù)器會壓縮HTML文檔。對腳本和樣式表進(jìn)行壓 縮同 樣也是值得做的事情,但是很多web服務(wù)器都沒有這個(gè)功能。實(shí)際上,壓縮任何一個(gè)文本類型的響應(yīng),包括XML和JSON,都值得的。圖像和PDF文件由于 已經(jīng)壓縮過了所以不能再進(jìn)行g(shù)zip壓縮。如果試圖gizp壓縮這些文件的話不但會浪費(fèi)CPU資源還會增加文件的大小。?
? ?Gzip壓縮所有可能的文件類型是減少文件體積增加用戶體驗(yàn)的簡單方法。
?
14、配置ETag?
??Entity tags(ETags)(實(shí)體標(biāo)簽)是web服務(wù)器和瀏覽器用于判斷瀏覽器緩存中的內(nèi)容和服務(wù)器中的原始內(nèi)容是否匹配的一種機(jī)制(“實(shí)體”就是所說的“內(nèi) 容”,包括圖片、腳本、樣式表等)。增加ETag為實(shí)體的驗(yàn)證提供了一個(gè)比使用“l(fā)ast-modified date(上次編輯時(shí)間)”更加靈活的機(jī)制。Etag是一個(gè)識別內(nèi)容版本號的唯一字符串。唯一的格式限制就是它必須包含在雙引號內(nèi)。原始服務(wù)器通過含有 ETag文件頭的響應(yīng)指定頁面內(nèi)容的ETag。?
? ?? ?HTTP/1.1 200 OK
? ?? ?Last-Modified: Tue, 12 Dec 2006 03:03:59 GMT
? ?? ?ETag: "10c24bc-4ab-457e1c1f"
? ?? ?Content-Length: 12195
??稍后,如果瀏覽器要驗(yàn)證一個(gè)文件,它會使用If-None-Match文件頭來把ETag傳回給原始服務(wù)器。在這個(gè)例子中,如果ETag匹配,就會返 回一 個(gè)304狀態(tài)碼,這就節(jié)省了12195字節(jié)的響應(yīng)。? ?? ?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的問題在于,它是根據(jù)可以辨別網(wǎng)站所在的服務(wù)器的具有唯一性的屬性來生成的。當(dāng)瀏覽器從一臺服務(wù)器上獲得頁面內(nèi)容后到另外一臺服務(wù)器上進(jìn)行驗(yàn) 證時(shí) ETag就會不匹配,這種情況對于使用服務(wù)器組和處理請求的網(wǎng)站來說是非常常見的。默認(rèn)情況下,Apache和IIS都會把數(shù)據(jù)嵌入ETag中,這會顯著 減少多服務(wù)器間的文件驗(yàn)證沖突。
? ?Apache 1.3和2.x中的ETag格式為inode-size-timestamp。即使某個(gè)文件在不同的服務(wù)器上會處于相同的目錄下,文件大小、權(quán)限、時(shí)間戳 等都完全相同,但是在不同服務(wù)器上他們的內(nèi)碼也是不同的。?
??IIS 5.0和IIS 6.0處理ETag的機(jī)制相似。IIS中的ETag格式為Filetimestamp:ChangeNumber。用ChangeNumber來跟蹤 IIS配置的改變。網(wǎng)站所用的不同IIS服務(wù)器間ChangeNumber也不相同。不同的服務(wù)器上的Apache和IIS即使對于完全相同的內(nèi)容產(chǎn)生的 ETag在也不相同,用戶并不會接收到一個(gè)小而快的304響應(yīng);相反他們會接收一個(gè)正常的200響應(yīng)并下載全部內(nèi)容。如果你的網(wǎng)站只放在一臺服務(wù)器上,就 不會存在這個(gè)問題。但是如果你的網(wǎng)站是架設(shè)在多個(gè)服務(wù)器上,并且使用Apache和 IIS產(chǎn)生默認(rèn)的ETag配置,你的用戶獲得頁面就會相對慢一點(diǎn),服務(wù)器會傳輸更多的內(nèi)容,占用更多的帶寬,代理也不會有效地緩存你的網(wǎng)站內(nèi)容。即使你的 內(nèi)容擁有Expires文件頭,無論用戶什么時(shí)候點(diǎn)擊“刷新”或者“重載”按鈕都會發(fā)送相應(yīng)的GET請求。
? ?如果你沒有使用ETag提供的靈活的驗(yàn)證模式,那么干脆把所有的ETag都去掉會更好。Last-Modified文件頭驗(yàn)證是基于內(nèi)容的時(shí)間戳的。去 掉 ETag文件頭會減少響應(yīng)和下次請求中文件的大小。微軟的這篇支持文稿講述了如何去掉ETag。在Apache中,只需要在配置文件中簡單添加下面一行代 碼就可以了:
? ?? ?FileETag none
?
15、盡早刷新輸出緩沖
?
??當(dāng)用戶請求一個(gè)頁面時(shí),無論如何都會花費(fèi)200到500毫秒用于后臺組織HTML文件。在這期間,瀏覽器會一直空閑等待數(shù)據(jù)返回。在PHP中,你可以 使用 flush()方法,它允許你把已經(jīng)編譯的好的部分HTML響應(yīng)文件先發(fā)送給瀏覽器,這時(shí)瀏覽器就會可以下載文件中的內(nèi)容(腳本等)而后臺同時(shí)處理剩余的 HTML頁面。這樣做的效果會在后臺煩惱或者前臺較空閑時(shí)更加明顯。
??輸出緩沖應(yīng)用最好的一個(gè)地方就是緊跟在<head />之后,因?yàn)镠TML的頭部分容易生成而且頭部往往包含CSS和JavaScript文件,這樣瀏覽器就可以在后臺編譯剩余HTML的同時(shí)并行下 載它們。 例子:
? ?? ?... <!-- css, js -->
? ?? ?? ? </head>
? ?? ?? ? <?php flush(); ?>
? ?? ?? ? <body>
? ?? ?... <!-- content -->
為了證明使用這項(xiàng)技術(shù)的好處,Yahoo!搜索率先研究并完成了用戶測試。
?
16、使用GET來完成AJAX請求
?
??Yahoo!Mail團(tuán)隊(duì)發(fā)現(xiàn),當(dāng)使用XMLHttpRequest時(shí),瀏覽器中的POST方法是一個(gè)“兩步走”的過程:首先發(fā)送文件頭,然后才發(fā)送 數(shù) 據(jù)。因此使用GET最為恰當(dāng),因?yàn)樗恍璋l(fā)送一個(gè)TCP包(除非你有很多cookie)。IE中URL的最大長度為2K,因此如果你要發(fā)送一個(gè)超過2K的 數(shù)據(jù)時(shí)就不能使用GET了。
??一個(gè)有趣的不同就是POST并不像GET那樣實(shí)際發(fā)送數(shù)據(jù)。根據(jù)HTTP規(guī)范,GET意味著“獲取”數(shù)據(jù),因此當(dāng)你僅僅獲取數(shù)據(jù)時(shí)使用GET更加有意義 (從語意上講也是如此),相反,發(fā)送并在服務(wù)端保存數(shù)據(jù)時(shí)使用POST。
?
除此之外,JavaScript和CSS也是我們頁面中經(jīng)常用到的內(nèi)容,對它們的優(yōu)化也提高網(wǎng)站性能的重要方面:
?
35、避免空的圖像來源
一個(gè)src屬性為空串的圖像有兩種情況:
1. 直接的HTML
<img src="">
2. JavaScript
var img = new Image();
img.src = "";
?
這兩種情況都會引起同樣的效果:瀏覽器會再次向你的服務(wù)器發(fā)出請求。
- Internet Explorer? 將向這個(gè)頁面所在的目錄發(fā)出一個(gè)請求
- Safari and Chrome? 將發(fā)出對這個(gè)頁面的一個(gè)請求。
- Firefox 3? 和更早的版本所采取的動(dòng)作和Safari and Chrome一樣,但是 3.5版本 addressed this issue [bug 444931] ?and no longer sends a request.
- Opera? 不進(jìn)行任何操作。
這個(gè)行為為何是不好的?
1、 發(fā)送大量突然的請求將使你的服務(wù)器宕機(jī)(Cripple your servers),尤其是每天有數(shù)百萬訪問量的頁面。
2、 產(chǎn)生一個(gè)從未瀏覽過的頁面將浪費(fèi)服務(wù)器的計(jì)算周期(computing cycles)
3、 損壞用戶數(shù)據(jù)。如果你在請求中追蹤狀態(tài)(以cookie或是其他的方式),你可能會損壞數(shù)據(jù)。即使這個(gè)圖像請求并沒有返回一個(gè)圖像,所有的頭被瀏覽器讀取 并接受,包括所有cookie。While the rest of the response is thrown away, the damage may already be done.
引 起這種行為的根源在于瀏覽器中URI的解析方式。這種行為定義在RFC 3986 - Uniform Resource Identifiers.當(dāng)一個(gè)空串作為一個(gè)URI時(shí),它被認(rèn)為一個(gè)相對URI(relative URI)并通過定義在section 5.2中的算法被解析。這個(gè)特例,一個(gè)空串,列在section 5.4當(dāng)中。Firefox, Safari, and Chrome都是依據(jù)這一規(guī)格來解析空串,而Internet Explorer則不正確的解析這個(gè)串,符合更早的一個(gè)規(guī)范,RFC 2396 - Uniform Resource Identifiers (this was obsoleted by RFC 3986).所以技術(shù)上,瀏覽器都在做它們被期望所做的事情來解析relative URIs,問題是在這個(gè)范圍,空串不是故意造成的。
?
HTML5 adds to the description of the file:///C:/Users/Prayer/AppData/Local/Temp/msohtmlclip1/01/clip_image001.giftag's src attribute to instruct browsers not to make an additional request in section 4.8.2:
? ? The src attribute must be present, and must contain a valid URL referencing a non-interactive, optionally animated, image resource that is neither paged nor scripted. If the base URI of the element is the same as the document's address, then the src attribute's value must not be the empty string.
非常希望瀏覽器在將來不會有這樣的問題。不幸的是,沒有為<script src=""> and <link href="">的條款。或許仍需要時(shí)間來做出調(diào)整以保證瀏覽器不會意外的實(shí)現(xiàn)這一行為。
這一規(guī)則是受雅虎JavaScript導(dǎo)師Nicolas C. Zakas啟發(fā)。更新信息請參見 Empty image src can destroy your site. .
三、CSS部分
- 把樣式表置于頂部
- 避免使用CSS表達(dá)式(Expression)
- 用<link>代替@import
- 避免使用濾鏡
?
17、把樣式表置于頂部
?
??在研究Yahoo!的性能表現(xiàn)時(shí),我們發(fā)現(xiàn)把樣式表放到文檔的<head />內(nèi)部似乎會加快頁面的下載速度。這是因?yàn)榘褬邮奖矸诺?lt;head />內(nèi)會使頁面有步驟的加載顯示。
??注重性能的前端服務(wù)器往往希望頁面有秩序地加載。同時(shí),我們也希望瀏覽器把已經(jīng)接收到內(nèi)容盡可能顯示出來。這對于擁有較多內(nèi)容的頁面和網(wǎng)速較慢的用戶 來說 特別重要。向用戶返回可視化的反饋,比如進(jìn)程指針,已經(jīng)有了較好的研究并形成了正式文檔。在我們的研究中HTML頁面就是進(jìn)程指針。當(dāng)瀏覽器有序地加載文 件頭、導(dǎo)航欄、頂部的logo等對于等待頁面加載的用戶來說都可以作為可視化的反饋。這從整體上改善了用戶體驗(yàn)。
??把樣式表放在文檔底部的問題是在包括Internet Explorer在內(nèi)的很多瀏覽器中這會中止內(nèi)容的有序呈現(xiàn)。瀏覽器中止呈現(xiàn)是為了避免樣式改變引起的頁面元素重繪。用戶不得不面對一個(gè)空白頁面。
? ?HTML規(guī)范清楚指出樣式表要放包含在頁面的<head />區(qū)域內(nèi):“和<a />不同,<link />只能出現(xiàn)在文檔的<head />區(qū)域內(nèi),盡管它可以多次使用它”。無論是引起白屏還是出現(xiàn)沒有樣式化的內(nèi)容都不值得去嘗試。最好的方案就是按照HTML規(guī)范在文 檔<head />內(nèi)加載你的樣式表。
?
18、避免使用CSS表達(dá)式(Expression)?
??CSS表達(dá)式是動(dòng)態(tài)設(shè)置CSS屬性的強(qiáng)大(但危險(xiǎn))方法。Internet Explorer從第5個(gè)版本開始支持CSS表達(dá)式。下面的例子中,使用CSS表達(dá)式可以實(shí)現(xiàn)隔一個(gè)小時(shí)切換一次背景顏色:
? ?? ?background-color: expression( (new Date()).getHours()%2 ? "#B8D4FF" : "#F08A00" );?
如上所示,expression中使用了JavaScript表達(dá)式。CSS屬性根據(jù)JavaScript表達(dá)式的計(jì)算結(jié)果來設(shè)置。expression 方法在其它瀏覽器中不起作用,因此在跨瀏覽器的設(shè)計(jì)中單獨(dú)針對Internet Explorer設(shè)置時(shí)會比較有用。
??表達(dá)式的問題就在于它的計(jì)算頻率要比我們想象的多。不僅僅是在頁面顯示和縮放時(shí),就是在頁面滾動(dòng)、乃至移動(dòng)鼠標(biāo)時(shí)都會要重新計(jì)算一次。給CSS表達(dá)式增加 一個(gè)計(jì)數(shù)器可以跟蹤表達(dá)式的計(jì)算頻率。在頁面中隨便移動(dòng)鼠標(biāo)都可以輕松達(dá)到10000次以上的計(jì)算量。
??一個(gè)減少CSS表達(dá)式計(jì)算次數(shù)的方法就是使用一次性的表達(dá)式,它在第一次運(yùn)行時(shí)將結(jié)果賦給指定的樣式屬性,并用這個(gè)屬性來代替CSS表達(dá)式。如果樣式 屬性 必須在頁面周期內(nèi)動(dòng)態(tài)地改變,使用事件句柄來代替CSS表達(dá)式是一個(gè)可行辦法。如果必須使用CSS表達(dá)式,一定要記住它們要計(jì)算成千上萬次并且可能會對你 頁面的性能產(chǎn)生影響。
?
19、用<link>代替@import
?
??前面的最佳實(shí)現(xiàn)中提到CSS應(yīng)該放置在頂端以利于有序加載呈現(xiàn)。
??在IE中,頁面底部@import和使用<link>作用是一樣的,因此最好不要使用它。
?
20、避免使用濾鏡
?
??IE獨(dú)有屬性AlphaImageLoader用于修正7.0以下版本中顯示PNG圖片的半透明效果。這個(gè)濾鏡的問題在于瀏覽器加載圖片時(shí)它會終止內(nèi)容的 呈現(xiàn)并且凍結(jié)瀏覽器。在每一個(gè)元素(不僅僅是圖片)它都會運(yùn)算一次,增加了內(nèi)存開支,因此它的問題是多方面的。
??完全避免使用AlphaImageLoader的最好方法就是使用PNG8格式來代替,這種格式能在IE中很好地工作。如果你確實(shí)需要使用 AlphaImageLoader,請使用下劃線_filter又使之對IE7以上版本的用戶無效。
?
四、 JavaScript部分
- 把腳本置于頁面底部
- 使用外部JavaScript和CSS
- 削減JavaScript和CSS
- 剔除重復(fù)腳本
- 減少DOM訪問
- 開發(fā)智能事件處理程序
?
21、把腳本置于頁面底部
?
??腳本帶來的問題就是它阻止了頁面的平行下載。HTTP/1.1 規(guī)范建議,瀏覽器每個(gè)主機(jī)名的并行下載內(nèi)容不超過兩個(gè)。如果你的圖片放在多個(gè)主機(jī)名上,你可以在每個(gè)并行下載中同時(shí)下載2個(gè)以上的文件。但是當(dāng)下載腳本 時(shí),瀏覽器就不會同時(shí)下載其它文件了,即便是主機(jī)名不相同。
??在某些情況下把腳本移到頁面底部可能不太容易。比如說,如果腳本中使用了document.write來插入頁面內(nèi)容,它就不能被往下移動(dòng)了。這里可能還 會有作用域的問題。很多情況下,都會遇到這方面的問題。
??一個(gè)經(jīng)常用到的替代方法就是使用延遲腳本。DEFER屬性表明腳本中沒有包含document.write,它告訴瀏覽器繼續(xù)顯示。不幸的 是,F(xiàn)irefox并不支持DEFER屬性。在Internet Explorer中,腳本可能會被延遲但效果也不會像我們所期望的那樣。如果腳本可以被延遲,那么它就可以移到頁面的底部。這會讓你的頁面加載的快一點(diǎn)。
?
22、使用外部JavaScript和CSS?
??很多性能規(guī)則都是關(guān)于如何處理外部文件的。但是,在你采取這些措施前你可能會問到一個(gè)更基本的問題:JavaScript和CSS是應(yīng)該放在外部文件中呢 還是把它們放在頁面本身之內(nèi)呢?
??在實(shí)際應(yīng)用中使用外部文件可以提高頁面速度,因?yàn)镴avaScript和CSS文件都能在瀏覽器中產(chǎn)生緩存。內(nèi)置在HTML文檔中的 JavaScript 和CSS則會在每次請求中隨HTML文檔重新下載。這雖然減少了HTTP請求的次數(shù),卻增加了HTML文檔的大小。從另一方面來說,如果外部文件中的 JavaScript和CSS被瀏覽器緩存,在沒有增加HTTP請求次數(shù)的同時(shí)可以減少HTML文檔的大小。
??關(guān)鍵問題是,外部JavaScript和CSS文件緩存的頻率和請求HTML文檔的次數(shù)有關(guān)。雖然有一定的難度,但是仍然有一些指標(biāo)可以一測量它。如 果一 個(gè)會話中用戶會瀏覽你網(wǎng)站中的多個(gè)頁面,并且這些頁面中會重復(fù)使用相同的腳本和樣式表,緩存外部文件就會帶來更大的益處。
??許多網(wǎng)站沒有功能建立這些指標(biāo)。對于這些網(wǎng)站來說,最好的堅(jiān)決方法就是把JavaScript和CSS作為外部文件引用。比較適合使用內(nèi)置代碼的例外 就是 網(wǎng)站的主頁,如Yahoo!主頁和My Yahoo!。主頁在一次會話中擁有較少(可能只有一次)的瀏覽量,你可以發(fā)現(xiàn)內(nèi)置JavaScript和CSS對于終端用戶來說會加快響應(yīng)時(shí) 間。
??對于擁有較大瀏覽量的首頁來說,有一種技術(shù)可以平衡內(nèi)置代碼帶來的HTTP請求減少與通過使用外部文件進(jìn)行緩存帶來的好處。其中一個(gè)就是在首頁中內(nèi)置 JavaScript和CSS,但是在頁面下載完成后動(dòng)態(tài)下載外部文件,在子頁面中使用到這些文件時(shí),它們已經(jīng)緩存到瀏覽器了。
?
23、削減JavaScript和CSS?
??精簡是指從去除代碼不必要的字符減少文件大小從而節(jié)省下載時(shí)間。消減代碼時(shí),所有的注釋、不需要的空白字符(空格、換行、tab縮進(jìn))等都要去掉。在 JavaScript中,由于需要下載的文件體積變小了從而節(jié)省了響應(yīng)時(shí)間。精簡JavaScript中目前用到的最廣泛的兩個(gè)工具是JSMin和YUI Compressor。YUI Compressor還可用于精簡CSS。
??混淆是另外一種可用于源代碼優(yōu)化的方法。這種方法要比精簡復(fù)雜一些并且在混淆的過程更易產(chǎn)生問題。在對美國前10大網(wǎng)站的調(diào)查中發(fā)現(xiàn),精簡也可以縮小 原來 代碼體積的21%,而混淆可以達(dá)到25%。盡管混淆法可以更好地縮減代碼,但是對于JavaScript來說精簡的風(fēng)險(xiǎn)更小。
??除消減外部的腳本和樣式表文件外,<script>和<style>代碼塊也可以并且應(yīng)該進(jìn)行消減。即使你用Gzip壓縮過 腳本 和樣式表,精簡這些文件仍然可以節(jié)省5%以上的空間。由于JavaScript和CSS的功能和體積的增加,消減代碼將會獲得益處。
?
24、剔除重復(fù)腳本
?
??在同一個(gè)頁面中重復(fù)引用JavaScript文件會影響頁面的性能。你可能會認(rèn)為這種情況并不多見。對于美國前10大網(wǎng)站的調(diào)查顯示其中有兩家存在重 復(fù)引 用腳本的情況。有兩種主要因素導(dǎo)致一個(gè)腳本被重復(fù)引用的奇怪現(xiàn)象發(fā)生:團(tuán)隊(duì)規(guī)模和腳本數(shù)量。如果真的存在這種情況,重復(fù)腳本會引起不必要的HTTP請求和 無用的JavaScript運(yùn)算,這降低了網(wǎng)站性能。
??在Internet Explorer中會產(chǎn)生不必要的HTTP請求,而在Firefox卻不會。在Internet Explorer中,如果一個(gè)腳本被引用兩次而且它又不可緩存,它就會在頁面加載過程中產(chǎn)生兩次HTTP請求。即時(shí)腳本可以緩存,當(dāng)用戶重載頁面時(shí)也會產(chǎn) 生額外的HTTP請求。
??除增加額外的HTTP請求外,多次運(yùn)算腳本也會浪費(fèi)時(shí)間。在Internet Explorer和Firefox中不管腳本是否可緩存,它們都存在重復(fù)運(yùn)算JavaScript的問題。
??一個(gè)避免偶爾發(fā)生的兩次引用同一腳本的方法是在模板中使用腳本管理模塊引用腳本。在HTML頁面中使用<script />標(biāo)簽引用腳本的最常見方法就是:?
? ? <script type="text/javascript" src="menu_1.0.17.js"></script>?
在PHP中可以通過創(chuàng)建名為insertScript的方法來替代:?
? ???<?php insertScript("menu.js") ?>?
為了防止多次重復(fù)引用腳本,這個(gè)方法中還應(yīng)該使用其它機(jī)制來處理腳本,如檢查所屬目錄和為腳本文件名中增加版本號以用于Expire文件頭等。
?
25、減少DOM訪問
?
??使用JavaScript訪問DOM元素比較慢,因此為了獲得更多的應(yīng)該頁面,應(yīng)該做到:
緩存已經(jīng)訪問過的有關(guān)元素?
線下更新完節(jié)點(diǎn)之后再將它們添加到文檔樹中?
避免使用JavaScript來修改頁面布局?
??有關(guān)此方面的更多信息請查看Julien Lecomte在YUI專題中的文章“高性能Ajax應(yīng)該程序”。
?
26、開發(fā)智能事件處理程序
?
??有時(shí)候我們會感覺到頁面反應(yīng)遲鈍,這是因?yàn)镈OM樹元素中附加了過多的事件句柄并且些事件句病被頻繁地觸發(fā)。這就是為什么說使用event delegation(事件代理)是一種好方法了。如果你在一個(gè)div中有10個(gè)按鈕,你只需要在div上附加一次事件句柄就可以了,而不用去為每一個(gè)按 鈕增加一個(gè)句柄。事件冒泡時(shí)你可以捕捉到事件并判斷出是哪個(gè)事件發(fā)出的。
??你同樣也不用為了操作DOM樹而等待onload事件的發(fā)生。你需要做的就是等待樹結(jié)構(gòu)中你要訪問的元素出現(xiàn)。你也不用等待所有圖像都加載完畢。
??你可能會希望用DOMContentLoaded事件來代替 事件應(yīng)用程序中的onAvailable方法。
??有關(guān)此方面的更多信息請查看Julien Lecomte在YUI專題中的文章“高性能Ajax應(yīng)該程序”。
?
圖片和Coockie也是我們網(wǎng)站中幾乎不可缺少組成部分,此外隨著移動(dòng)設(shè)備的流行,對于移動(dòng)應(yīng)用的優(yōu)化也十分重要。這主要包括:
五、Coockie部分
- 減小Cookie體積
- 對于頁面內(nèi)容使用無coockie域名
?
27、減小Cookie體積
?
??HTTP coockie可以用于權(quán)限驗(yàn)證和個(gè)性化身份等多種用途。coockie內(nèi)的有關(guān)信息是通過HTTP文件頭來在web服務(wù)器和瀏覽器之間進(jìn)行交流的。因此 保持coockie盡可能的小以減少用戶的響應(yīng)時(shí)間十分重要。
有關(guān)更多信息可以查看Tenni Theurer和Patty Chi的文章“When the Cookie Crumbles”。這們研究中主要包括:
去除不必要的coockie
使coockie體積盡量小以減少對用戶響應(yīng)的影響?
注意在適應(yīng)級別的域名上設(shè)置coockie以便使子域名不受影響?
設(shè)置合理的過期時(shí)間。較早地Expire時(shí)間和不要過早去清除coockie,都會改善用戶的響應(yīng)時(shí)間。
?
28、對于頁面內(nèi)容使用無coockie域名
?
??當(dāng)瀏覽器在請求中同時(shí)請求一張靜態(tài)的圖片和發(fā)送coockie時(shí),服務(wù)器對于這些coockie不會做任何地使用。因此他們只是因?yàn)槟承┴?fù)面因素而創(chuàng) 建的 網(wǎng)絡(luò)傳輸。所有你應(yīng)該確定對于靜態(tài)內(nèi)容的請求是無coockie的請求。創(chuàng)建一個(gè)子域名并用他來存放所有靜態(tài)內(nèi)容。
? ?如果你的域名是
http://www.example.org/
?,你可以在static.example.org上存在靜態(tài)內(nèi)容。但是,如果你不是在
http://www.example.org/
?上而是在頂級域名example.org設(shè)置了coockie,那么所有對于static.example.org的請求都包含coockie。在這種情 況下,你可以再重新購買一個(gè)新的域名來存在靜態(tài)內(nèi)容,并且要保持這個(gè)域名是無coockie的。Yahoo!使用的是ymig.com,YouTube使 用的是ytimg.com,Amazon使用的是images-anazon.com等等。
??使用無coockie域名存在靜態(tài)內(nèi)容的另外一個(gè)好處就是一些代理(服務(wù)器)可能會拒絕對coockie的內(nèi)容請求進(jìn)行緩存。一個(gè)相關(guān)的建議就是,如果你 想確定應(yīng)該使用example.org還是
http://www.example.org/
?作為你的一主頁,你要考慮到coockie帶來的影響。忽略掉www會使你除了把coockie設(shè)置到*.example.org(*是泛域名解析,代表 了所有子域名譯者dudo注)外沒有其它選擇,因此出于性能方面的考慮最好是使用帶有www的子域名并且在它上面設(shè)置coockie。
?
六、Image 部分
- 優(yōu)化圖像
- 優(yōu)化CSS Spirite
- 不要在HTML中縮放圖像
- favicon.ico 要小而且可緩存
?
29、優(yōu)化圖像
?
??設(shè)計(jì)人員完成對頁面的設(shè)計(jì)之后,不要急于將它們上傳到web服務(wù)器,這里還需要做幾件事:
你可以檢查一下你的GIF圖片中圖像顏色的數(shù)量是否和調(diào)色板規(guī)格一致。 使用imagemagick中下面的命令行很容易檢查:
? ?? ?identify -verbose image.gif?
如果你發(fā)現(xiàn)圖片中只用到了4種顏色,而在調(diào)色板的中顯示的256色的顏色槽,那么這張圖片就還有壓縮的空間。
??嘗試把GIF格式轉(zhuǎn)換成PNG格式,看看是否節(jié)省空間。大多數(shù)情況下是可以壓縮的。由于瀏覽器支持有限,設(shè)計(jì)者們往往不太樂意使用PNG格式的圖片, 不過 這都是過去的事情了。現(xiàn)在只有一個(gè)問題就是在真彩PNG格式中的alpha通道半透明問題,不過同樣的,GIF也不是真彩格式也不支持半透明。因此GIF 能做到的,PNG(PNG8)同樣也能做到(除了動(dòng)畫)。下面這條簡單的命令可以 安全地把GIF格式轉(zhuǎn)換為PNG格式:
? ?? ?convert image.gif image.png
“我們要說的是:給PNG一個(gè)施展身手的機(jī)會吧!”?
在所有的PNG圖片上運(yùn)行pngcrush(或者其它PNG優(yōu)化工具)。例如:
? ?? ?pngcrush image.png -rem alla -reduce -brute result.png?
在所有的JPEG圖片上運(yùn)行jpegtran。這個(gè)工具可以對圖片中的出現(xiàn)的鋸齒等做無損操作,同時(shí)它還可以用于優(yōu)化和清除圖片中的注釋以及其它無用信息 (如EXIF信息):
? ?? ?jpegtran -copy none -optimize -perfect src.jpg dest.jpg
?
30、優(yōu)化CSS Spirite
?
??在Spirite中水平排列你的圖片,垂直排列會稍稍增加文件大小;?
Spirite中把顏色較近的組合在一起可以降低顏色數(shù),理想狀況是低于256色以便適用PNG8格式;?
??便于移動(dòng),不要在Spirite的圖像中間留有較大空隙。這雖然不大會增加文件大小但對于用戶代理來說它需要更少的內(nèi)存來把圖片解壓為像素地圖。 100x100的圖片為1萬像素,而1000x1000就是100萬像素。
?
31、不要在HTML中縮放圖像
?
??不要為了在HTML中設(shè)置長寬而使用比實(shí)際需要大的圖片。如果你需要:
<img width="100" height="100" src="mycat.jpg" alt="My Cat" />
那么你的圖片(mycat.jpg)就應(yīng)該是100x100像素而不是把一個(gè)500x500像素的圖片縮小使用。
?
32、favicon.ico要小而且可緩存
?
??favicon.ico是位于服務(wù)器根目錄下的一個(gè)圖片文件。它是必定存在的,因?yàn)榧词鼓悴魂P(guān)心它是否有用,瀏覽器也會對它發(fā)出請求,因此最好不要返 回一 個(gè)404 Not Found的響應(yīng)。由于是在同一臺服務(wù)器上,它每被請求一次coockie就會被發(fā)送一次。這個(gè)圖片文件還會影響下載順序,例如在IE中當(dāng)你在 onload中請求額外的文件時(shí),favicon會在這些額外內(nèi)容被加載前下載。
??因此,為了減少favicon.ico帶來的弊端,要做到:
文件盡量地小,最好小于1K?
在適當(dāng)?shù)臅r(shí)候(也就是你不要打算再換favicon.ico的時(shí)候,因?yàn)楦鼡Q新文件時(shí)不能對它進(jìn)行重命名)為它設(shè)置Expires文件頭。你可以很安全地 把Expires文件頭設(shè)置為未來的幾個(gè)月。你可以通過核對當(dāng)前favicon.ico的上次編輯時(shí)間來作出判斷。?
Imagemagick可以幫你創(chuàng)建小巧的favicon。
?
七、 Mobile部分
- 保持單個(gè)內(nèi)容小于25K
- 打包組件成復(fù)合文本
?
33、保持單個(gè)內(nèi)容小于25K
?
??這條限制主要是因?yàn)閕Phone不能緩存大于25K的文件。注意這里指的是解壓縮后的大小。由于單純gizp壓縮可能達(dá)不要求,因此精簡文件就顯得十分重 要。
??查看更多信息,請參閱Wayne Shea和Tenni Theurer的文件“Performance Research, Part 5: iPhone Cacheability - Making it Stick”。
?
34、打包組件成復(fù)合文本
?
??把頁面內(nèi)容打包成復(fù)合文本就如同帶有多附件的Email,它能夠使你在一個(gè)HTTP請求中取得多個(gè)組件(切記:HTTP請求是很奢侈的)。當(dāng)你使用這條規(guī) 則時(shí),首先要確定用戶代理是否支持(iPhone就不支持)。
……(35、避免空的圖像來源 在 二、服務(wù)器部分)
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
