網站(zhàn)頁面性能(néng)優化(huà)的(de)20條黃(huáng)金(jīn)守則
1、用(yòng)<link>代替@import
前面的(de)最佳實現(xiàn)中提到(dào)CSS應該放(fàng)置在頂端以利于有(yǒu)序加載呈現(xiàn)。 &n→bsp;
在IE中,頁面底部@import和(hé)使用(yòng)
作(zuò)用(yòng)是(shì)一(yī)樣的(de),因此最好(hǎo)不(bù)要(yào)使用(yòng)它。
2、避免使用(yòng)濾鏡
IE獨有(yǒu)屬性AlphaImageLoader用(yòng)于修正7.0以下(xià)版本中顯示PNG圖片的(de)半透明(míng)效果。這(zhè)個©(gè)濾鏡的(de)問(wèn)題在于浏覽器(qì)加載圖片時(shí)它會(huì)終止內(nèi)容的(de)呈現(xiàn)并且凍結浏覽器(qì)。在每一(yī)個(gè)元素(♠不(bù)僅僅是(shì)圖片)它都(dōu)會(huì)運算(suàn)一(yī)次,增加了(le)內(nèi)存開(kāi)支,因此它的(de)問(wèn)題是(shì)多(duō)方面的("de)。
完全避免使用(yòng)AlphaImageLoader的(de)最好(hǎo)方法就(jiù)是(shγì)使用(yòng)PNG8格式來(lái)代替,這(zhè)種格式能(néng)在IE中很(hěn)好(hǎo)地(dì)工(gōng)作(→zuò)。如(rú)果你(nǐ)确實需要(yào)使用(yòng)AlphaImageLoader,請(qǐn✘g)使用(yòng)下(xià)劃線_filter又(yòu)使之對(duì)IE7以上(shàng)版本的(de)用★(yòng)戶無效。
3、把腳本置于頁面底部
腳本帶來(lái)的(de)問(wèn)題就(jiù)是(shì)它阻止了(le)頁面的(de)平行(xíng)下(xià)載。HTT÷P/1.1 規範建議(yì),浏覽器(qì)每個(gè)主機(jī)名的(de)并行(xíng)下(xià)載內(nèi)♥容不(bù)超過兩個(gè)。如(rú)果你(nǐ)的(de)圖片放(fàng)在多(duō)個(gè)主機(jī)名 上(shàng),你(nǐ)可(kě)以在每個(gè)并行(xíng)下(xià)載中同時(shí)下(xià)載2個(€gè)以上(shàng)的(de)文(wén)件(jiàn)。但(dàn)是(shì)當下(xià)載腳本時(shí),浏覽器(qì)就(jiù)不(bù)會(huì) 同時(shí)下(xià)載其它文(wén)件(jiàn)了(le),即便是(shì)主機(jī)名不(bù)相(xiàng)同。 &nbs₩p;
在某些(xiē)情況下(xià)把腳本移到(dào)頁面底部可(kě)能(néng)不(bù)太容易。比如(rú)說(shuō),如(rú)果腳本中使用(yòng∞)了(le)document.write來(lái)插入頁面內(nèi)容,它就(jiù)不(bù)能(néng)被往α下(xià)移動了(le)。這(zhè)裡(lǐ)可(kě)能(néng)還(hái)會(huì)有(yǒu)作(zuò)用(yòng)域的(de)問(wèn)題。很(hěn)多(du ō)情況下(xià),都(dōu)會(huì)遇到(dào)這(zhè)方面的(de)問(wèn)題。
一(yī)個(gè)經常用(yòng)到(dào)的(de)替代方法就(jiù)是(shì)使用(yòng)延遲腳本。DEFE¶R屬性表明(míng)腳本中沒有(yǒu)包含document.write,它告訴浏覽器(qì)繼續顯示。不(bù)幸的(de•)是(shì),Firefox并不(bù)支持DEFER屬性。在Internet Explorer中,腳本可(kě)能(n$éng)會(huì)被延遲但(dàn)效果也(yě)不(bù)會(huì)像我們所期望的(de)那(nà)樣。如(rú)果腳本可(kě)以被延遲,那(nà)麽™它就(jiù)可(kě)以移到(dào)頁面的(de)底部。這(zhè)會(huì)讓你(nǐ)的(de)頁面加載的(d$e)快(kuài)一(yī)點。
4、剔除重複腳本
在同一(yī)個(gè)頁面中重複引用(yòng)JavaScript文(wén)件(jiàn)會(huì)影(yǐng)響頁面的<(de)性能(néng)。你(nǐ)可(kě)能(néng)會(huì)認為(wèi)這(zhè)種情況并不(bù)多(duō)見(jiàn)。對(duì)于美(měi)國(guó)前10大$(dà)網站(zhàn)的(de)調查顯示其中有(yǒu)兩家(jiā)存在重複引用(yòng)腳本的(de)情況。有(yǒu)→兩種主要(yào)因素導緻一(yī)個(gè)腳本被重複引用(yòng)的(de)奇怪現(xiàn)象發生(shēng):團隊規模和(hé)腳本φ數(shù)量。如(rú)果真的(de)存在這(zhè)種情況,重複腳本會(huì)引起不(bù)必要(yào)的(de)HTTP請(qǐng)求和(hé)無用(y→òng)的(de)JavaScript運算(suàn),這(zhè)降低(dī)了(le)網站(zhàn)性能(néng)。 ✔
在Internet Explorer中會(huì)産生(shēng)不(bù)必要(yào)的(de)HTTP請(qǐng)求,而在Firefox卻不(bù)會(h&uì)。在Internet Explorer中,如(rú)果一(yī)個(gè)腳本被引用(yòng)兩次而且它又(yòu)不(bù)可(kě)緩存,它就(jiù)會(huì)在頁"面加載過程中産生(shēng)兩次HTTP請(qǐng)求。即時(shí)腳本可(kě)以緩存,當用(yòng)戶重載頁面時(shí)也(yě)會(huì)産生(shēng)額外(wài)的( de)HTTP請(qǐng)求。
除增加額外(wài)的(de)HTTP請(qǐng)求外(wài),多(duō)次運算(suàn)腳本也(yě)會(huì)浪費(fèi)時(shí)間(jiān)₽。在Internet Explorer和(hé)Firefox中不(bù)管腳本是(shì)否可(kě)緩存,它們都(dōu)存在重 複運算(suàn)JavaScript的(de)問(wèn)題。
一(yī)個(gè)避免偶爾發生(shēng)的(de)兩次引用(yòng)同一(yī)腳本的(de)δ方法是(shì)在模闆中使用(yòng)腳本管理(lǐ)模塊引用(yòng)腳本。在HTML頁面中使用(yòng)
标簽引用(yòng)腳本的(de)最常見(jiàn)方法就(jiù)是(shì):
<script type="text/javascript" src="™menu_1.0.17.js">
在PHP中可(kě)以通(tōng)過創建名為(wèi)insertScript的(de)方法來(lái)替代:
為(wèi)了(le)防止多(duō)次重複引用(yòng)腳本,這(zhè)個(gè)方法中還(hái)應該使用(yòng)其它機(jī)制(zhì)來(lái)處理(lǐ)腳本©,如(rú)檢查所屬目錄和(hé)為(wèi)腳本文(wén)件(jiàn)名中增加版本号以用(yòng)于Expire文(wén)件(jiàn)頭等。
5、減少(shǎo)DOM訪問(wèn)
使用(yòng)JavaScript訪問(wèn)DOM元素比較慢(màn),因此為(wèi)了(le)獲得(de)更多(d★uō)的(de)應該頁面,應該做(zuò)到(dào):緩存已經訪問(wèn)過的(de)有(yǒu)關元素₩ 線下(xià)更新完節點之後再将它們添加到(dào)文(wén)檔樹(shù)中 避免使用(yòng)JavaScript來(lái)修改 頁面布局
有(yǒu)關此方面的(de)更多(duō)信息請(qǐng)查看(kàn)Julien Lecomte在YUI專題中的(de)文(wén)章(zhāng)“高(gāo)性能(néng)A₩jax應該程序”。
6、開(kāi)發智能(néng)事(shì)件(jiàn)處理(lǐ)程序
有(yǒu)時(shí)候我們會(huì)感覺到(dào)頁面反應遲鈍,這(zhè)是(shì)因為(wèi)DOM樹(shù)元λ素中附加了(le)過多(duō)的(de)事(shì)件(jiàn)句柄并且些(xiē)事(shì)件(jiàn)句病被頻(pín)繁地(dì)觸發。這(zhè)就(jiù)是(shì)為(wèi)什(shén)麽說 (shuō)使用(yòng)event delegation(事(shì)件(jiàn)代理(lǐ))是(s✔hì)一(yī)種好(hǎo)方法了(le)。如(rú)果你(nǐ)在一(yī)個(gè)div中有(yǒu)10個(gè)按鈕,你(nǐ)隻需要(yào)在div上(βshàng)附加一(yī)次事(shì)件(jiàn)句柄就(jiù)可(kě)以了(le),而不(bù)用( yòng)去(qù)為(wèi)每一(yī)個(gè)按鈕增加一(yī)個(gè)句柄。事(shì)件(jiàn)冒泡時(shí)你(nǐ)可(kě)以捕捉到(dào)事(shì)件(j∏iàn)并判斷出是(shì)哪個(gè)事(shì)件(jiàn)發出的(de)。 &n∑bsp;
你(nǐ)同樣也(yě)不(bù)用(yòng)為(wèi)了(le)操作(zuò)DOM樹(shù)而等待onload事(shì)件(jiàn)的(de)發生(shēng)。你(nǐ)需 要(yào)做(zuò)的(de)就(jiù)是(shì)等待樹(shù)結構中你(nǐ)要(yào)訪問(wèn)的(de)元素出現(xiàn)。你(nǐ)也(yě)不(bù)用(yò∞ng)等待所有(yǒu)圖像都(dōu)加載完畢。
你(nǐ)可(kě)能(néng)會(huì)希望用(yòng)DOMContentLoaded事(shì)σ件(jiàn)來(lái)代替onload,但(dàn)是(shì)在所有(yǒu)浏覽器(qì)都(®dōu)支持它之前你(nǐ)可(kě)使用(yòng)YUI 事(shì)件(jiàn)應用(yòng)程序中的(de)onAvailable方法。
7、減小(xiǎo)Cookie體(tǐ)積
HTTP coockie可(kě)以用(yòng)于權限驗證和(hé)個(gè)性化(huà)身(shēn)份等多(duαō)種用(yòng)途。coockie內(nèi)的(de)有(yǒu)關信息是(shì)通(tōng)過HTTP文(wén)件(λjiàn)頭來(lái)在web服務器(qì)和(hé)浏覽器(qì)之間(jiān)進行(xíng)交流的(de)。因此保持coockie盡可(kě)¶能(néng)的(de)小(xiǎo)以減少(shǎo)用(yòng)戶的(de)響應時(shí)間(jiān)十分(fēn)重要(yào)。 有(yǒu)✔關更多(duō)信息可(kě)以查看(kàn)Tenni Theurer和(hé)Patty ChiΩ的(de)文(wén)章(zhāng)“When the Cookie Crumbles”。這(zhè)們研究中主要(yào)×包括:去(qù)除不(bù)必要(yào)的(de)coockie 使coockie體(tǐ)積盡量小(xiǎo)以減少(shǎo)對(duì)用(yòng)戶響應的(de )影(yǐng)響 注意在适應級别的(de)域名上(shàng)設置coockie以便使子(zǐ)域♦名不(bù)受影(yǐng)響 設置合理(lǐ)的(de)過期時(shí)間(jiān)。較早地(dì)Expi↓re時(shí)間(jiān)和(hé)不(bù)要(yào)過早去(qù)清除coockie,都(dōu)會(huì)改σ善用(yòng)戶的(de)響應時(shí)間(jiān)。
8、對(duì)于頁面內(nèi)容使用(yòng)無coockie域名
當浏覽器(qì)在請(qǐng)求中同時(shí)請(qǐng)求一(yī)張靜(jìng)态的(de)圖片和(&hé)發送coockie時(shí),服務器(qì)對(duì)于這(zhè)些(xiē)coockie不(bù)會(↓huì)做(zuò)任何地(dì)使用(yòng)。因此他(tā)們隻是(shì)因為(wèi)某些(♥xiē)負面因素而創建的(de)網絡傳輸。所有(yǒu)你(nǐ)應該确定對(duì)于靜(jìng)态內(nèi)容的(de)請(qǐng)求是(shì)無coock ie的(de)請(qǐng)求。創建一(yī)個(gè)子(zǐ)域名并用(yòng)他(tā)來(lái)存放(fàng&)所有(yǒu)靜(jìng)态內(nèi)容。
如(rú)果你(nǐ)的(de)域名是(shì)www.example.org,你(nǐ)可(kě)以在static.example.org上(shàng)存在靜(jìng)态內(nè↓i)容。但(dàn)是(shì),如(rú)果你(nǐ)不(bù)是(shì)在www.example.org上(shàng)而是(shì)在頂級域名example.org設置了(le)coock₩ie,那(nà)麽所有(yǒu)對(duì)于static.example.org的(de)請(qǐng)求都(dōu)包含coocβkie。在這(zhè)種情況下(xià),你(nǐ)可(kě)以再重新購(gòu)買一(yī)個(gè)新的(de)域名來(lái)存在靜(jìng)态內(nèi)容,并<且要(yào)保持這(zhè)個(gè)域名是(shì)無coockie的(de)。Yahoo!使用(yòng)的(de)是(s∞hì)ymig.com,YouTube使用(yòng)的(de)是(shì)ytimg.com,Amazon使用(yòng)的(de)是(shì)images-an→azon.com等等。
使用(yòng)無coockie域名存在靜(jìng)态內(nèi)容的(de)另外(wài)一(yī)個(gè€)好(hǎo)處就(jiù)是(shì)一(yī)些(xiē)代理(lǐ)(服務器(qì))可(kě)能(néng)會(huì)拒®絕對(duì)coockie的(de)內(nèi)容請(qǐng)求進行(xíng)緩存。一(yī)個(gè)相(xiàng)關的(de)建議(yì)就(jiù)是(s₹hì),如(rú)果你(nǐ)想确定應該使用(yòng)example.org還(hái)是(shì)www.example.org作(zuò)為(wèi)你(nǐ)的(de)一(yī)®主頁,你(nǐ)要(yào)考慮到(dào)coockie帶來(lái)的(de)影(yǐng)響。忽略掉www會(huì)使你(nǐ)除了(le)把coockie設置到(dào)*.example∏.org(*是(shì)泛域名解析,代表了(le)所有(yǒu)子(zǐ)域名譯者dudo注)外(wài)沒有(yǒu)其它選擇,因此出于性能(néng)方$面的(de)考慮最好(hǎo)是(shì)使用(yòng)帶有(yǒu)www的(de)子(zǐ)域名并且在它上(shàng)面設置coockie。
9、優化(huà)圖像
設計(jì)人(rén)員(yuán)完成對(duì)頁面的(de)設計(jì)之後,不(bù)要(yào)急于∏将它們上(shàng)傳到(dào)web服務器(qì),這(zhè)裡(lǐ)還(hái)需要(yào)做(zuò)ε幾件(jiàn)事(shì):你(nǐ)可(kě)以檢查一(yī)下(xià)你(nǐ)的(de)GIF圖片中圖像顔色的(de)數(shù)量是(shì)否和(hé)調色闆規格一(yī)緻。 使用(yòng)imagemagick中下(xià)面的(de)命令行(xíng)很(✔hěn)容易檢查: identify -verbose image.gif 如(rú)果你(nǐ)發現(xiàn)圖片中隻用(yòng)到(dào)了(l>e)4種顔色,而在調色闆的(de)中顯示的(de)256色的(de)顔色槽,那(nà)麽這(zhè)張圖片就(jiù)還(hái)有(yǒu)壓縮的(de)空λ(kōng)間(jiān)。
嘗試把GIF格式轉換成PNG格式,看(kàn)看(kàn)是(shì)否節省空(kōng)間(jiān)。大(dà)多(duō)數(shù)情況下(xiπà)是(shì)可(kě)以壓縮的(de)。由于浏覽器(qì)支持有(yǒu)限,設計(jì)者們往往不(bù)太樂(yuè)意使用(yòng)PNG格式的(de)圖片,不(bù)過這(zhè)©都(dōu)是(shì)過去(qù)的(de)事(shì)情了(le)。現(xiàn)在隻有(yǒu)一(yī)個(gè)問(wèn)題就(jiù)₹是(shì)在真彩PNG格式中的(de)alpha通(tōng)道(dào)半透明(míng)問(wèn)題,不(bù)過同樣的(de),G≤IF也(yě)不(bù)是(shì)真彩格式也(yě)不(bù)支持半透明(míng)。因此GIF能(néng)做(zuò)到(dào)的(de),PNG(PNG8)同樣↕也(yě)能(néng)做(zuò)到(dào)(除了(le)動畫(huà))。下(xià)面這(zhè)條簡單的(de)命令可(kě)以安全地(dì)把GI∞F格式轉換為(wèi)PNG格式: convert image.gif image.png “我們要(yào)說(shuō)的(de)是(shì):給PNG一(yī)個(gè)施展身(™shēn)手的(de)機(jī)會(huì)吧(ba)!” 在所有(yǒu)的(de)PNG圖片上(shàng)運行✔(xíng)pngcrush(或者其它PNG優化(huà)工(gōng)具)。例如(rú): pngcru₽sh image.png -rem alla -reduce -brute result.png 在所有(yγǒu)的(de)JPEG圖片上(shàng)運行(xíng)jpegtran。這(zhè)個(gè)工(gōng)具可(kě)以對(duì)圖片中的(de)出現(xiàn)的(de)∑鋸齒等做(zuò)無損操作(zuò),同時(shí)它還(hái)可(kě)以用(yòng)于優化(huà)和(hé)清除圖片中的(de)注釋以©及其它無用(yòng)信息(如(rú)EXIF信息): jpegtran -copy none -optimize -perfect src.jpg dest.jpg
10、優化(huà)CSS不(bù)要(yào)出現(xiàn)404錯(cuò)誤
Spirite在Spirite中水(shuǐ)平排列你(nǐ)的(de)圖片,垂直排列會(huì)稍稍增加文(wén)件(jiλàn)大(dà)小(xiǎo); Spirite中把顔色較近(jìn)的(de)組合在一(yī)起可(kě)以降低(dī)顔色≤數(shù),理(lǐ)想狀況是(shì)低(dī)于256色以便适用(yòng)PNG8格式; 便于移動,不(bù)要(yào)在Spirite的(de)圖像中間(jiān)留有(yǒu)±較大(dà)空(kōng)隙。這(zhè)雖然不(bù)大(dà)會(huì)增加文(wén)件(jiàn)大(dà)小(xiǎo)但$(dàn)對(duì)于用(yòng)戶代理(lǐ)來(lái)說(shuō)它需要(yào)更少(s≈hǎo)的(de)內(nèi)存來(lái)把圖片解壓為(wèi)像素地(dì)圖。100x100的(de☆)圖片為(wèi)1萬像素,而1000x1000就(jiù)是(shì)100萬像素。
HTTP請(qǐng)求時(shí)間(jiān)消耗是(shì)很(hěn)大(dà)的(de),因此使用(yòng)HTTP請(qǐ±ng)求來(lái)獲得(de)一(yī)個(gè)沒有(yǒu)用(yòng)處的(de)響應(例如(rú)404沒有(yǒu)找到(dào)頁面)是(shì)完全沒有(yǒu)必要(y←ào)的(de),它隻會(huì)降低(dī)用(yòng)戶體(tǐ)驗而不(bù)會(huì)有(yǒu)一(yī)ε點好(hǎo)處。
有(yǒu)些(xiē)站(zhàn)點把404錯(cuò)誤響應頁面改為(wèi)“你(nǐ)是(&shì)不(bù)是(shì)要(yào)找***”,這(zhè)雖然改進了(le)用(yòng)戶體(tǐ)驗但(dàn)是(shì)同樣也(y→ě)會(huì)浪費(fèi)服務器(qì)資源(如(rú)數(shù)據庫等)。最糟糕的(de)情況是(shì)指向外(wài)部JavaScri"pt的(de)鏈接出現(xiàn)問(wèn)題并返回404代碼。首先,這(zhè)種加載會(huì)破壞并行♣(xíng)加載;其次浏覽器(qì)會(huì)把試圖在返回的(de)404響應內(nèi)容中找到(dào)可(kě)能(néng)Ω有(yǒu)用(yòng)的(de)部分(fēn)當作(zuò)JavaScript代碼來(lái)執行(xíng)。
11、使用(yòng)內(nèi)容分(fēn)發網絡
用(yòng)戶與你(nǐ)網站(zhàn)服務器(qì)的(de)接近(jìn)程度會(huì)影(σyǐng)響響應時(shí)間(jiān)的(de)長(cháng)短(duǎn)。把你(nǐ)的(de)網站(zhàn)內☆(nèi)容分(fēn)散到(dào)多(duō)個(gè)、處于不(bù)同地(dì)域位置的(de)服務器(qì)上(shàng)可(k'ě)以加快(kuài)下(xià)載速度。但(dàn)是(shì)首先我們應該做(zuò)些(xiē)什(shén)麽呢(ne)? &n±bsp;
按地(dì)域布置網站(zhàn)內(nèi)容的(de)第一(yī)步并不(bù)是(shì)要(yào)嘗試重新架構你(nǐ)的(de)網站(zhàn)讓他(tā)們在分(fēn)φ發服務器(qì)上(shàng)正常運行(xíng)。根據應用(yòng)的(de)需求來(lái)改變網站(zhàn)結構,這(zhè)可(kě)能(nén¥g)會(huì)包括一(yī)些(xiē)比較複雜(zá)的(de)任務,如(rú)在服務器(qì)間(jiān)同≥步Session狀态和(hé)合并數(shù)據庫更新等。要(yào)想縮短(duǎn)用(yòng)戶和(hé)內(nèi)容服務器(qì)的(§de)距離(lí),這(zhè)些(xiē)架構步驟可(kě)能(néng)是(shì)不(bù)可(kě)避免的(de)。 ≈
要(yào)記住,在終端用(yòng)戶的(de)響應時(shí)間(jiān)中有(yǒu)80%到(dào)90%的(d e)響應時(shí)間(jiān)用(yòng)于下(xià)載圖像、樣式表、腳本、Flash等頁面內(nèi)容。這(zhè)就(jiù)是(shì)網站(zhàn)性能(néng)黃(huáng)金(jīn)守則。和(hé)重新設計(jì)你(nǐ)的(de)應用(yòng)程序架構↑這(zhè)樣比較困難的(de)任務相(xiàng)比,首先來(lái)分(fēn)布靜(jìng)φ态內(nèi)容會(huì)更好(hǎo)一(yī)點。這(zhè)不(bù)僅會(huì)縮短(duǎn)響應時(shí)間(ji₩ān),而且對(duì)于內(nèi)容分(fēn)發網絡來(lái)說(shuō)它更容易實現(xiàn)。
內(nèi)容分(fēn)發網絡(Content Delivery Network,CDN)是(shì)由一(yī) 系列分(fēn)散到(dào)各個(gè)不(bù)同地(dì)理(lǐ)位置上(shàng)的(de)Web服務器(qì)組成的(de),它提高(gāo)了(✘le)網站(zhàn)內(nèi)容的(de)傳輸速度。用(yòng)于向用(yòng)戶傳輸內(nèi)容的(de)服務器(qì)主要®(yào)是(shì)根據和(hé)用(yòng)戶在網絡上(shàng)的(de)靠近(jìn)程度來(lái)指定的(de)。例如(rú),擁有(≠yǒu)最少(shǎo)網絡跳(tiào)數(shù)(network hops)和(hé)響應速度最快(kuài)的(de)服務器(qì)會(huì)∑被選定。
一(yī)些(xiē)大(dà)型的(de)網絡公司擁有(yǒu)自(zì)己的(de)CDN,但(dàn)是(shì)使用(yòng¶)像Akamai Technologies,Mirror Image Internet, 或者Limelight ✘Networks這(zhè)樣的(de)CDN服務成本卻非常高(gāo)。對(duì)于剛剛起步的(de)企業(yè)和(hé)€個(gè)人(rén)網站(zhàn)來(lái)說(shuō),可(kě)能(néng)沒有(yǒu)使用(yòng)CDN的(de)成本預算(suà↑n),但(dàn)是(shì)随著(zhe)目标用(yòng)戶群的(de)不(bù)斷擴大(dà)和(hé)更加全球化(huà),CDN就(jiù)是(shì)實現(xiàn)快σ(kuài)速響應所必需的(de)了(le)。以Yahoo來(lái)說(shuō),他(tā)們轉移到(dào)CDN上(shàng)γ的(de)網站(zhàn)程序靜(jìng)态內(nèi)容節省了(le)終端用(yòng)戶20%以上(shàng)的π(de)響應時(shí)間(jiān)。使用(yòng)CDN是(shì)一(yī)個(gè)隻需要(yào)相(xiàn♦g)對(duì)簡單地(dì)修改代碼實現(xiàn)顯著改善網站(zhàn)訪問(wèn)速度的(de)方法。
12、為(wèi)文(wén)件(jiàn)頭指定Expires或Cache-Control
這(zhè)條守則包括兩方面的(de)內(nèi)容: 對(duì)于靜(jìng)态內(nèi)容:設π置文(wén)件(jiàn)頭過期時(shí)間(jiān)Expires的(de)值為(wèi)“Neve₹r expire”(永不(bù)過期) 對(duì)于動态內(nèi)容:使用(yòng)恰當的(de)Cache-Control文(wén)件(jiàn)頭來(lái)幫助浏覽器(qì)↕進行(xíng)有(yǒu)條件(jiàn)的(de)請(qǐng)求
網頁內(nèi)容設計(jì)現(xiàn)在越來(lái)越豐富,這(zhè)就(jiù)意味著(zhe)頁面中要(yào)包含更多(duō)的(de)腳本、樣式表、圖片和(hé)Flash。第一(yī)次訪問(wèn)你(nǐ)頁面的(de)用(yòng)戶就(jiù)意味著(zhe£)進行(xíng)多(duō)次的(de)HTTP請(qǐng)求,但(dàn)是(shì)通(tōng)過使用(yòng)Expires文(wén)件(jiàn)"頭就(jiù)可(kě)以使這(zhè)樣內(nèi)容具有(yǒu)緩存性。它避免了(le)接下(xià)來(lái)的(de)頁面訪問(wèn)中不(bù)必要(yào)的(de)HTTP請♦(qǐng)求。Expires文(wén)件(jiàn)頭經常用(yòng)于圖像文(wén)件(jiàn),但(dàn)是(shì)應該在所有(yǒu)的(de)內(nèi)容都(dōu)✘使用(yòng)他(tā),包括腳本、樣式表和(hé)Flash等。
浏覽器(qì)(和(hé)代理(lǐ))使用(yòng)緩存來(lái)減少(shǎo)HTTP請(qǐng)₽求的(de)大(dà)小(xiǎo)和(hé)次數(shù)以加快(kuài)頁面訪問(wèn)速度。Web服務器(qì)在HTTP響應↕中使用(yòng)Expires文(wén)件(jiàn)頭來(lái)告訴客戶端內(nèi)容需要(yào)緩存多(duō)長(c↕háng)時(shí)間(jiān)。下(xià)面這(zhè)個(gè)例子(zǐ)是(shì)一(yī)個(gè)較長(cháng)時(shí)間(jiā§n)的(de)Expires文(wén)件(jiàn)頭,它告訴浏覽器(qì)這(zhè)個(gè)響應直到(dào)2010年(nián)4月(yuè)15日(rì)才過期。 × Expires: Thu, 15 Apr 2010 20:00:00 GMT &nb©sp; 如(rú)果你(nǐ)使用(yòng)的(de)是(shì)Apache服務器(qì),可(k™ě)以使用(yòng)ExpiresDefault來(lái)設定相(xiàng)對(duì)當前日(rì)期的(de)過期時(shí)間(jiān)。下(xià)面這(zhè)個(gè)β例子(zǐ)是(shì)使用(yòng)ExpiresDefault來(lái)設定請(qǐng)求時(shí)間(jiān)後10年(nián)過ε期的(de)文(wén)件(jiàn)頭:
ExpiresDefault "access plus 10 years"
要(yào)切記,如(rú)果使用(yòng)了(le)Expires文(wén)件(jiàn)頭,當頁面內(nèi)容改變時÷(shí)就(jiù)必須改變內(nèi)容的(de)文(wén)件(jiàn)名。依Yahoo!來(lái)說(shuō)我們經常使用(yòng)∞這(zhè)樣的(de)步驟:在內(nèi)容的(de)文(wén)件(jiàn)名中加上(shàng)¥版本号,如(rú)yahoo_2.0.6.js。
使用(yòng)Expires文(wén)件(jiàn)頭隻有(yǒu)會(huì)在用(yòng)戶已經訪問(wèδn)過你(nǐ)的(de)網站(zhàn)後才會(huì)起作(zuò)用(yòng)。當用(yòng)戶首次訪問(wèn)你(nǐ)的(dδe)網站(zhàn)時(shí)這(zhè)對(duì)減少(shǎo)HTTP請(qǐng)求次數(shù)來(lái)說(s☆huō)是(shì)無效的(de),因為(wèi)浏覽器(qì)的(de)緩存是(shì)空(kōng)的(de)。因此這(zhè)種方法對(duì)于你(nǐ)網站(zhàn)性✘能(néng)的(de)改進情況要(yào)依據他(tā)們“預緩存”存在時(shí)對(duì)你(nǐ)頁面的(de₽)點擊頻(pín)率(“預緩存”中已經包含了(le)頁面中的(de)所有(yǒu)內(nèi)容)。Yahoo!建立了(le)一(yī≠)套測量方法,我們發現(xiàn)所有(yǒu)的(de)頁面浏覽量中有(yǒu)75~85%都(dōu)有(yǒu)“預緩存”。通(tōnλg)過使用(yòng)Expires文(wén)件(jiàn)頭,增加了(le)緩存在浏覽器(qì)中內(nèi)容的(de)數(shù)量,并且可(kě)以在用(yòng)✘戶接下(xià)來(lái)的(de)請(qǐng)求中再次使用(yòng)這(zhè)些(xiē)內(nèi)容,這(zhè)甚至都(dōu)不(bù)需要(yào)通(tōng)過用(yòn¥g)戶發送一(yī)個(gè)字節的(de)請(qǐng)求。
13、Gzip壓縮文(wén)件(jiàn)內(nèi)容
網絡傳輸中的(de)HTTP請(qǐng)求和(hé)應答(dá)時(shí)間(jiān)可(kě)以通(tōng)過前端機(jī)制(zhì)得(de)到(dào)顯著改¥善。的(de)确,終端用(yòng)戶的(de)帶寬、互聯網提供者、與對(duì)等交換點的(de)靠近(jìn)程度等都(dōu)不(bù)是( shì)網站(zhàn)開(kāi)發者所能(néng)決定的(de)。但(dàn)是(shì)還(hái)有(yǒu)其他(tā)因素影(yǐng)響著(zhe)響應★時(shí)間(jiān)。通(tōng)過減小(xiǎo)HTTP響應的(de)大(dà)小(xiǎo)可(kě↑)以節省HTTP響應時(shí)間(jiān)。
從(cóng)HTTP/1.1開(kāi)始,web客戶端都(dōu)默認支持HTTP請(qǐng)求中有(yǒu)Accept-Encoding文(wén)件(jiàn)頭的(d↓e)壓縮格式:Accept-Encoding: gzip, deflate
如(rú)果web服務器(qì)在請(qǐng)求的(de)文(wén)件(jiàn)頭中檢測到(dào)上(shàng)面的(de)代碼,就±(jiù)會(huì)以客戶端列出的(de)方式壓縮響應內(nèi)容。Web服務器(qì)把壓縮方式通(tōng)過響應文(wén)件(₹jiàn)頭中的(de)Content-Encoding來(lái)返回給浏覽器(qì)。
Content-Encoding: gzip
Gzip是(shì)目前最流行(xíng)也(yě)是(shì)最有(yǒu)效的(de)壓縮方式。這(zhè)是(¥shì)由GNU項目開(kāi)發并通(tōng)過RFC 1952來(lái)标準化(huà)的(de)。另外(wài)僅↕有(yǒu)的(de)一(yī)個(gè)壓縮格式是(shì)deflate,但(dàn)是(shì)它的(de)使用(yòng)™範圍有(yǒu)限效果也(yě)稍稍遜色。
Gzip大(dà)概可(kě)以減少(shǎo)70%的(de)響應規模。目前大(dà)約有(yǒu)90%通(tōng)過浏覽器(qì)傳輸的(de)互聯網交換支持gzip格式。如•(rú)果你(nǐ)使用(yòng)的(de)是(shì)Apache,gzip模塊配置和(hé)你(nǐ)的(de)版本有(yǒu)關:Apache∑ 1.3使用(yòng)mod_zip,而Apache 2.x使用(yòng)moflate。
浏覽器(qì)和(hé)代理(lǐ)都(dōu)會(huì)存在這(zhè)樣的(de)問(wèn)題:浏覽器(qì)期Ω望收到(dào)的(de)和(hé)實際接收到(dào)的(de)內(nèi)容會(huì)存在不(bù)匹配的(de)現(xiàn>)象。幸好(hǎo),這(zhè)種特殊情況随著(zhe)舊(jiù)式浏覽器(qì)使用(yòng)量的(de)減少(shǎo)在減少(s₽hǎo)。Apache模塊會(huì)通(tōng)過自(zì)動添加适當的(de)Vary響應文(wén)件(jiàn)頭來(lái)避免這(zhè)種狀況的(de)出現(xiàn)。 &n≥bsp;
服務器(qì)根據文(wén)件(jiàn)類型來(lái)選擇需要(yào)進行(xíng)gzi↓p壓縮的(de)文(wén)件(jiàn),但(dàn)是(shì)這(zhè)過于限制(zhì)了(le)可(kě)壓縮的(de)文(wén)件(jiàn)。大(dà)多(duō)數(shù)web服務器(qì)會(huì)壓縮HTML文(wén)檔。對(duì)腳本和(hé)樣α式表進行(xíng)壓縮同樣也(yě)是(shì)值得(de)做(zuò)的(de)事(shì)情,但(dàn)是(shì)很(hěn)多(duō)w♦eb服務器(qì)都(dōu)沒有(yǒu)這(zhè)個(gè)功能(néng)。實際上(shàng),壓縮任何一(yī)個(gè)文£(wén)本類型的(de)響應,包括XML和(hé)JSON,都(dōu)值得(de)的(de)。圖像和(hé)PDF文(wén)件(jiàn)由于已經壓縮過了(le)所以不(bù)能(néng)再進行(xíng)gzip壓縮。如(rú)果試圖gizp壓縮這(zhè)些(x&iē)文(wén)件(jiàn)的(de)話(huà)不(bù)但(dàn)會(huì)浪費(fèi)CPU資源還(hái)會(huì)增加文(wén)件(jiàn)♦的(de)大(dà)小(xiǎo)。
Gzip壓縮所有(yǒu)可(kě)能(néng)的(de)文(wén)件(jiàn)類型是(shì)¥減少(shǎo)文(wén)件(jiàn)體(tǐ)積增加用(yòng)戶體(tǐ)驗的(de)簡單方法。
14、配置ETag
Entity tags(ETags)(實體(tǐ)标簽)是(shì)web服務器(qì)和(hé)浏覽器(qì)用(yòng)于判斷浏覽器(qì)緩存中的(de)內(nèi↑)容和(hé)服務器(qì)中的(de)原始內(nèi)容是(shì)否匹配的(de)一(yī)種機(jī₹)制(zhì)(“實體(tǐ)”就(jiù)是(shì)所說(shuō)的(de)“內(nèi)容”,包括圖片、腳本、樣式表等)。增加ETag為(wèi)實體(πtǐ)的(de)驗證提供了(le)一(yī)個(gè)比使用(yòng)“last-modified date(上(shàng)次編輯時(shí)間(jiān))₹”更加靈活的(de)機(jī)制(zhì)。Etag是(shì)一(yī)個(gè)識别內(nèi)容♥版本号的(de)唯一(yī)字符串。唯一(yī)的(de)格式限制(zhì)就(jiù)是(shì)它必須包含在雙引号內(nèi)。原始服務器(§qì)通(tōng)過含有(yǒu)ETag文(wén)件(jiàn)頭的(de)響應指定頁面內(nèi)容的(de)ETag。
HTTP/1.1 200 OK Last-Modified: Tue, 12↕ Dec 2006 03:03:59 GMT ETag: "10c24bc-₩4ab-457e1c1f" Content-Length: 12195
稍後,如(rú)果浏覽器(qì)要(yào)驗證一(yī)個(gè)文(wén)件(jiàn),它會(huì)使用(yòng)If-Noneλ-Match文(wén)件(jiàn)頭來(lái)把ETag傳回給原始服務器(qì)。在這(zhè)個(gè)例子(zǐ)中,如(rú)果ETag匹配,就(jiù)會(huì)返回一σ(yī)個(gè)304狀态碼,這(zhè)就(jiù)節省了(le)12195字節的(de)響應。 " GET /i/yahoo.gif HTTP/1.1 Host♣: us.yimg.com If-Modified-Since: Tue, 12 Dec 2006 03:03:59 GMT &↓nbsp; If-None-Match: "10c24bc-4ab-457e1c1€f" HTTP/1.1 304 Not Modified ∏
ETag的(de)問(wèn)題在于,它是(shì)根據可(kě)以辨别網站(zhàn)所在的(de)服務器(qì)的(de)具有(yǒu)唯一(yī)性的(de)屬性來(lái)生(shēng)成的(de)。當浏覽器(qì)從(cóng)一(yī)台服務器(qì)上(shà•ng)獲得(de)頁面內(nèi)容後到(dào)另外(wài)一(yī)台服務器(qì)上(shàng)進行(xíng)驗證時(shí)ETag就(jiù)會(huì)不(bù)匹配,這(♦zhè)種情況對(duì)于使用(yòng)服務器(qì)組和(hé)處理(lǐ)請(qǐng)求的(de)網站(zhàn)來(lái)說(shuō)是(shì)非常常見(jiàn)的(de✔)。默認情況下(xià),Apache和(hé)IIS都(dōu)會(huì)把數(shù)據嵌入ETag中,這(zhè)會(huì)顯著減少(shǎo)多(¥duō)服務器(qì)間(jiān)的(de)文(wén)件(jiàn)驗證沖突。
Apache 1.3和(hé)2.x中的(de)ETag格式為(wèi)inode-size-timest®amp。即使某個(gè)文(wén)件(jiàn)在不(bù)同的(de)服務器(qì)上(shàng)會(huì)處于相(xiàng)同的(de)目錄下(xià),文(wéφn)件(jiàn)大(dà)小(xiǎo)、權限、時(shí)間(jiān)戳等都(dōu)完全相(xiàng)同,但(dàn)是(shì)在不(bù)同服務器(qì)上(shàng)他(tā)們的♦(de)內(nèi)碼也(yě)是(shì)不(bù)同的(de)。
IIS 5.0和(hé)IIS 6.0處理(lǐ)ETag的(de)機(jī)制(zhì)相(xiàng)似。IIS中的(de)ET♠ag格式為(wèi)Filetimestamp:ChangeNumber。用(yòng)ChangeNumber♦來(lái)跟蹤IIS配置的(de)改變。網站(zhàn)所用(yòng)的(de)不(bù)同IIS服務器(qì)間(jiān)ChangeNumber也(yě)不(bù)相(xiàng)≈同。 不(bù)同的(de)服務器(qì)上(shàng)的(de)Apache和(hé)IIS即使©對(duì)于完全相(xiàng)同的(de)內(nèi)容産生(shēng)的(de)ETag在也(yě)不(bù)相(xiàng)同,用(yòng)戶并不(bù♥)會(huì)接收到(dào)一(yī)個(gè)小(xiǎo)而快(kuài)的(de)304響應;相(xiàng)反他(tā)們會(huì)接收一(yī)個(gè)正常的(de)200響應并下(¥xià)載全部內(nèi)容。如(rú)果你(nǐ)的(de)網站(zhàn)隻放(fàng)在一(yī)台服務器(qì)上(shàng),就(jiù)不(bù)會(h∏uì)存在這(zhè)個(gè)問(wèn)題。但(dàn)是(shì)如(rú)果你(nǐ)的(de)網站(zhàn)是(shì)架設在多(duō)個(gè)服務器(qì)上(shàn≥g),并且使用(yòng)Apache和(hé)IIS産生(shēng)默認的(de)ETag配置,你(nǐ)的(de)用(yòng)戶獲得(de)頁面就(jiù)會(hu★ì)相(xiàng)對(duì)慢(màn)一(yī)點,服務器(qì)會(huì)傳輸更多(duō)的(de)內(nèi)容,占用(yòng)更多(duō)的(de)σ帶寬,代理(lǐ)也(yě)不(bù)會(huì)有(yǒu)效地(dì)緩存你(nǐ)的(de)網站(zhàn)內(nèi)容。即使你(nǐ)的β(de)內(nèi)容擁有(yǒu)Expires文(wén)件(jiàn)頭,無論用(yòng)戶什(shén)麽時(shí)候點擊“刷新”或者“重☆載”按鈕都(dōu)會(huì)發送相(xiàng)應的(de)GET請(qǐng)求。 &nb≠sp;
如(rú)果你(nǐ)沒有(yǒu)使用(yòng)ETag提供的(de)靈活的(de)驗證模式,那(nà)麽幹脆把所有(yǒu)的(de)ETag都(dōu)去(qù)掉會(huì)更好(hǎo)¶。Last-Modified文(wén)件(jiàn)頭驗證是(shì)基于內(nèi)容的(de)時(shí)間(ji♦ān)戳的(de)。去(qù)掉ETag文(wén)件(jiàn)頭會(huì)減少(shǎo)響應和(hé)下(xià)次請(qǐng)求中文(wén)件(jiàn")的(de)大(dà)小(xiǎo)。微(wēi)軟的(de)這(zhè)篇支持文(wén)稿講述了(le)如(rú)何去(qù)掉ETag。在Apache中,隻需"要(yào)在配置文(wén)件(jiàn)中簡單添加下(xià)面一(yī)行(xíng)代碼就(jiù)可(kě)以了(le):FileETag none
15、盡早刷新輸出緩沖
當用(yòng)戶請(qǐng)求一(yī)個(gè)頁面時(shí),無論如(rú)何都(dōu)會(huì)花(huā)費(fèi)200到(dào)500毫秒(miǎo)¥用(yòng)于後台組織HTML文(wén)件(jiàn)。在這(zhè)期間(jiān),浏覽器(qì)會(huì)一(yī)直空(kōng)閑等待•數(shù)據返回。在PHP中,你(nǐ)可(kě)以使用(yòng)flush()方法,它允許你(nǐ)把已經編譯的(de)好(hǎo)的(de)部分(fēn)HTML響應文(wé€n)件(jiàn)先發送給浏覽器(qì),這(zhè)時(shí)浏覽器(qì)就(jiù)會(huì)可(kě)以下(xià)載文(wén)件(jiàn)中的(de)內(nèi)容(腳本等)✘而後台同時(shí)處理(lǐ)剩餘的(de)HTML頁面。這(zhè)樣做(zuò)的(de)效果會(huì)在後台煩惱或者↓前台較空(kōng)閑時(shí)更加明(míng)顯。
輸出緩沖應用(yòng)最好(hǎo)的(de)一(yī)個(gè)地(dì)方就(jiù)是(shì)緊跟在之後,因為∏(wèi)HTML的(de)頭部分(fēn)容易生(shēng)成而且頭部往往包含CSS和(hé)Ja♠vaScript文(wén)件(jiàn),這(zhè)樣浏覽器(qì)就(jiù)可(kě)以在後台編譯剩餘HTML的(de)¶同時(shí)并行(xíng)下(xià)載它們。
為(wèi)了(le)證明(míng)使用(yòng)這(zhè)項技(jì)術(shù)的(de)好(hǎo)處,Yahoo!搜索率先研究并完成了(le)用(±yòng)戶測試。
16、使用(yòng)GET來(lái)完成AJAX請(qǐng)求
Yahoo!Mail團隊發現(xiàn),當使用(yòng)XMLHttpRequest時(shí),浏覽器(qì)中的(de)POST方法是(γshì)一(yī)個(gè)“兩步走”的(de)過程:首先發送文(wén)件(jiàn)頭,然後才發☆送數(shù)據。因此使用(yòng)GET最為(wèi)恰當,因為(wèi)它隻需發送一(yī)個(gè)TCP包(除非你(nǐ)有(yǒu)♥很(hěn)多(duō)cookie)。IE中URL的(de)最大(dà)長(cháng)度為(wèi)2K,因此如(rú)果你(nǐ)要(yào)發送一(yī)個(gè)超過2K的(de)數(shù)據時(shí)就(jiù)不(b≥ù)能(néng)使用(yòng)GET了(le)。
一(yī)個(gè)有(yǒu)趣的(de)不(bù)同就(jiù)是(shì)POST并不(bù)像G♣ET那(nà)樣實際發送數(shù)據。根據HTTP規範,GET意味著(zhe)“獲取”數(shù)據,因此當你(nǐ)僅僅獲取數(shù)據時(shí)¶使用(yòng)GET更加有(yǒu)意義(從(cóng)語意上(shàng)講也(yě)是(shì)如(rú)此),相(xiàng)反,發送并在服務端保存數(sh↓ù)據時(shí)使用(yòng)POST。
17、把樣式表置于頂部
在研究Yahoo!的(de)性能(néng)表現(xiàn)時(shí),我們發現(xiàn)把樣式表♦放(fàng)到(dào)文(wén)檔的(de)內(nèi)部似乎會(huì)加快(kuài)頁面的(de)下(xià)載速度。這(zhè)是(shì)因為(wèi)把樣式表放(f♠àng)到(dào)內(nèi)會(huì)使頁面有(yǒu)步驟的(de)加載顯示。
注重性能(néng)的(de)前端服務器(qì)往往希望頁面有(yǒu)秩序地(dì)加載。同時(shí),我們也(yě)希望浏覽器(qì)把已經接收到(dà¶o)內(nèi)容盡可(kě)能(néng)顯示出來(lái)。這(zhè)對(duì)于擁有(yǒu)₹較多(duō)內(nèi)容的(de)頁面和(hé)網速較慢(màn)的(de)用(yòng)戶來(lái)說(shuō)特别重要(yào)。向用(yòng)戶返回可(kě)視(shì)化×(huà)的(de)反饋,比如(rú)進程指針,已經有(yǒu)了(le)較好(hǎo)的(de)研究并形成了(le)正式文(wén)檔。在我們 的(de)研究中HTML頁面就(jiù)是(shì)進程指針。當浏覽器(qì)有(yǒu)序地(dì)加載文(wén)件(ji<àn)頭、導航欄、頂部的(de)logo等對(duì)于等待頁面加載的(de)用(yòng)戶來(lái)說(shuō)都(dōu)可(kě)以作(zuò)為(wèi)可(kě)視(shì)ε化(huà)的(de)反饋。這(zhè)從(cóng)整體(tǐ)上(shàng)改善了(le)用(yòng)戶體✘(tǐ)驗。
把樣式表放(fàng)在文(wén)檔底部的(de)問(wèn)題是(shì)在包括Internet Explorer在內(nèi)的(de)很(hěn)多(duō)浏覽器(qì)中這(zhè)∏會(huì)中止內(nèi)容的(de)有(yǒu)序呈現(xiàn)。浏覽器(qì)中止呈現(xiàn)是(shì)為(wèi)了(le)避免樣式改變引起的(de)頁面元素重繪。用(yòng)戶→不(bù)得(de)不(bù)面對(duì)一(yī)個(gè)空(kōng)白(bái)頁面。 ♦
HTML規範清楚指出樣式表要(yào)放(fàng)包含在頁面的(de)區(qū)域內(nèi):“和(hé₩)不(bù)同,隻能(néng)出現(xiàn)在文(wén)檔的(de)區(qū)域內(nèi),盡管它可(k≤ě)以多(duō)次使用(yòng)它”。無論是(shì)引起白(bái)屏還(hái)是(shì)出現(xiàn)沒有(yǒu)樣式化(huà)的(de )內(nèi)容都(dōu)不(bù)值得(de)去(qù)嘗試。最好(hǎo)的(de)方案就(jiù)是(shì)按照(zhào)HTML規範在文(wén)檔內(nèi)加載你(n•ǐ)的(de)樣式表。
18、避免使用(yòng)CSS表達式(Expression)
CSS表達式是(shì)動态設置CSS屬性的(de)強大(dà)(但(dàn)危險)方法。Internet Explorer從(cóng)第5個(gè)版本開(kāi)始支持CSS 表達式。下(xià)面的(de)例子(zǐ)中,使用(yòng)CSS表達式可(kě)以實現(xiàn)隔一(yī)個(gè)小(xiǎo)時(shí)切換一(yī)次背景顔色:background-color: expression( (new Date()).getHours()%2 ? "#B8D4FF&q♠uot; : "#F08A00" ); 如(rú)上(shàng)所示,expression中使用(yòng)了(le)←JavaScript表達式。CSS屬性根據JavaScript表達式的(de)計(jì)算(suàn)結果來&(lái)設置。expression方法在其它浏覽器(qì)中不(bù)起作(zuò)用(yòng),因此在跨浏覽器(qì)的(de)設計(jì)中單獨針對(duì)Inter☆net Explorer設置時(shí)會(huì)比較有(yǒu)用(yòng)。
表達式的(de)問(wèn)題就(jiù)在于它的(de)計(jì)算(suàn)頻(pín)率要(yào)比我們想象的(de)多(duō≈)。不(bù)僅僅是(shì)在頁面顯示和(hé)縮放(fàng)時(shí),就(jiù)是(shì)在頁面滾動、乃至移動鼠标時(shí)都(dōu)會(huì)要(yào)≈重新計(jì)算(suàn)一(yī)次。給CSS表達式增加一(yī)個(gè)計(jì)數(shù)器(qì)可(kě)以跟蹤表達式的(de)計(jì)算(su×àn)頻(pín)率。在頁面中随便移動鼠标都(dōu)可(kě)以輕松達到(dào)10000次以上 (shàng)的(de)計(jì)算(suàn)量。
一(yī)個(gè)減少(shǎo)CSS表達式計(jì)算(suàn)次數(shù)的(de)方法就(jiù)是(shì)使用(yòng)一(yī)次性的(de)表達式,它在第"一(yī)次運行(xíng)時(shí)将結果賦給指定的(de)樣式屬性,并用(yòng)這(zhè)個(g↓è)屬性來(lái)代替CSS表達式。如(rú)果樣式屬性必須在頁面周期內(nèi)動态地(dì)改變,使用(yòng)事(£shì)件(jiàn)句柄來(lái)代替CSS表達式是(shì)一(yī)個(gè)可(kě)行(xíng)辦法。如(rú)果必須使用(yòng)CSS表達式,一(yī)定要(yào)記住 它們要(yào)計(jì)算(suàn)成千上(shàng)萬次并且可(kě)能(néng)會(huì)對(duì)你(nǐ)頁面的(d©e)性能(néng)産生(shēng)影(yǐng)響。
19、使用(yòng)外(wài)部JavaScript和(hé)CSS
很(hěn)多(duō)性能(néng)規則都(dōu)是(shì)關于如(rú)何處理(lǐ)外(wài)部文(wén)件(jiàn)的(de)。但(dàn)是(shì),在你(nǐ)采取這(z★hè)些(xiē)措施前你(nǐ)可(kě)能(néng)會(huì)問(wèn)到(dào)一(yī)個(gè)更基本的(de)問(wèn)題:JavaS←cript和(hé)CSS是(shì)應該放(fàng)在外(wài)部文(wén)件(jiàn)中↓呢(ne)還(hái)是(shì)把它們放(fàng)在頁面本身(shēn)之內(nèi)呢(ne)?
在實際應用(yòng)中使用(yòng)外(wài)部文(wén)件(jiàn)可(kě)以提高(g āo)頁面速度,因為(wèi)JavaScript和(hé)CSS文(wén)件(jiàn)都(dōu)能(néng)在浏覽器(qì)中産生(shēng)緩存。內(nèi)置在HTML文(wén)δ檔中的(de)JavaScript和(hé)CSS則會(huì)在每次請(qǐng)求中随HTML文(wén)檔重δ新下(xià)載。這(zhè)雖然減少(shǎo)了(le)HTTP請(qǐng)求的(de)次數(shù),卻增加了(le)HTML文(wén)檔的(de)大(dà)小(&xiǎo)。從(cóng)另一(yī)方面來(lái)說(shuō),如(rú)果外(wài)部文(wén)件(jiàn)中的(de)JavaScript和(hé)CSS被浏覽器α(qì)緩存,在沒有(yǒu)增加HTTP請(qǐng)求次數(shù)的(de)同時(shí)可(kě)以減少(shǎβo)HTML文(wén)檔的(de)大(dà)小(xiǎo)。
關鍵問(wèn)題是(shì),外(wài)部JavaScript和(hé)CSS文(wén)件(jiàn)緩存的(de)頻(pín)率和(™hé)請(qǐng)求HTML文(wén)檔的(de)次數(shù)有(yǒu)關。雖然有(yǒu)一(yī)定的(de)難度,但(dàn)是(shì)仍然有(yǒu)一(yī)些(xiē)指标可(kě)以一(yī)測量它。如(rú)果一(yī)個(gè)會(huì)話(huà)中用(yòng)戶會(huì)浏覽你(nǐ)網站(zhàn)中的(de)多(duō)個(gè)頁面,并且這(zhè)些(xiē)頁面中會(huì)重複使>用(yòng)相(xiàng)同的(de)腳本和(hé)樣式表,緩存外(wài)部文(wén)件(jiàn)就(jiù)會(huì)帶來(lái)更大(dà)的(de)φ益處。
許多(duō)網站(zhàn)沒有(yǒu)功能(néng)建立這(zhè)些(xiē)指标。對(duì)于這(zhè)些(xiē)網站(zhàn)來(lái)說(sh↔uō),最好(hǎo)的(de)堅決方法就(jiù)是(shì)把JavaScript和(hé)CSS作(zuò)為(wèi)外(wà₽i)部文(wén)件(jiàn)引用(yòng)。比較适合使用(yòng)內(nèi)置代碼的(de)例外(wài)就(jiù)是(shì)網站(zhàn)的 (de)主頁,如(rú)Yahoo!主頁和(hé)My Yahoo!。主頁在一(yī)次會(huì)話(huà)中擁有(yǒu)較少(shǎo)(可(kě)能(néng)隻有(yǒu)一(→yī)次)的(de)浏覽量,你(nǐ)可(kě)以發現(xiàn)內(nèi)置JavaScript和(hé)CSS對(duì)于終端用(yòng)戶來(lái)說(shuō)會(×huì)加快(kuài)響應時(shí) 間(jiān)。
對(duì)于擁有(yǒu)較大(dà)浏覽量的(de)首頁來(lái)說(shuō),有(yǒu)一(yī)種技(jì)術(shù)可(kě)以σ平衡內(nèi)置代碼帶來(lái)的(de)HTTP請(qǐng)求減少(shǎo)與通(tōng)過使用(yòng)外(wài)☆部文(wén)件(jiàn)進行(xíng)緩存帶來(lái)的(de)好(hǎo)處。其中一(yī)個(gè)就(jiù)是(shì)在首頁中內(nèi)置JavaScript和(hé)C≈SS,但(dàn)是(shì)在頁面下(xià)載完成後動态下(xià)載外(wài)部文(wén)件(jiàn),在子(zǐ)頁面中®使用(yòng)到(dào)這(zhè)些(xiē)文(wén)件(jiàn)時(shí),它們已經緩存到(dào)浏覽器(qì)了(le)。
20、削減JavaScript和(hé)CSS
精簡是(shì)指從(cóng)去(qù)除代碼不(bù)必要(yào)的(de)字符減少(shǎo)文(wén)件(jiàn)大(dà≥)小(xiǎo)從(cóng)而節省下(xià)載時(shí)間(jiān)。消減代碼時(shí),所有(yǒu)的(de)注釋、不(bù)需要(yào)的(de)空(kōng)白(báiφ)字符(空(kōng)格、換行(xíng)、tab縮進)等都(dōu)要(yào)去(qù)掉。在JavaScript中,由于需要(yào)下(xià)載的(de)文(wén)件(jiàn)體(tǐ)積變小(xiǎo)了(le)從(cóng)而節省了(le)響應時(shí)間(jiānγ)。精簡JavaScript中目前用(yòng)到(dào)的(de)最廣泛的(de)兩個(gè)工(gōng)具是(shì)JSMin和(hé)YUI Compressor。YUI Compr≥essor還(hái)可(kě)用(yòng)于精簡CSS。
混淆是(shì)另外(wài)一(yī)種可(kě)用(yòng)于源代碼優化(huà)的(de)方法。這(zhè)種方法要(yào)$比精簡複雜(zá)一(yī)些(xiē)并且在混淆的(de)過程更易産生(shēng)問(wèn)題。在對≈(duì)美(měi)國(guó)前10大(dà)網站(zhàn)的(de)調查中發現(xiàn),精簡也(yě)可(kě)以縮小(xiǎ$o)原來(lái)代碼體(tǐ)積的(de)21%,而混淆可(kě)以達到(dào)25%。盡管混淆法可(kě)以更好(hǎo)地(dì)縮減∏代碼,但(dàn)是(shì)對(duì)于JavaScript來(lái)說(shuō)精簡的(de)風(fēng)險更小(xiǎo)。 ←
除消減外(wài)部的(de)腳本和(hé)樣式表文(wén)件(jiàn)外(wài),
