作者:瓜瓜 | 發(fā)布: (編輯)kent.zhu | 時(shí)間:2011-07-18 23:36:22文字大小:- +
本來這是個(gè)老生常談的問題,上周自成又分享了一些性能優(yōu)化的建議,我這里再做一個(gè)全面的Tips整理,謹(jǐn)作為查閱型的文檔,不妥之處,還請指正;
如果你已經(jīng)對yahoo這些優(yōu)化建議爛熟于心,果斷點(diǎn)這里
謹(jǐn)記:80%-90%的終端響應(yīng)時(shí)間是花費(fèi)在下載頁面中的圖片,樣式表,腳本,flash等;
詳細(xì)的解釋來這里查:http://developer.yahoo.com/performance/rules.html
也可以直接firebug上一項(xiàng)項(xiàng)比對,如下圖:
簡單翻譯解釋下:
1、盡量減少HTTP請求個(gè)數(shù)——須權(quán)衡
合并圖片(如css sprites,內(nèi)置圖片使用數(shù)據(jù))、合并CSS、JS,這一點(diǎn)很重要,但是要考慮合并后的文件體積。
2、使用CDN(內(nèi)容分發(fā)網(wǎng)絡(luò))
這里可以關(guān)注CDN的三類實(shí)現(xiàn):鏡像、高速緩存、專線,以及智能路由器和負(fù)載均衡;
3、為文件頭指定Expires或Cache-Control,使內(nèi)容具有緩存性。
區(qū)分靜態(tài)內(nèi)容和動態(tài)內(nèi)容,避免以后頁面訪問中不必要的HTTP請求。
4、避免空的src和href
留意具有這兩個(gè)屬性的標(biāo)簽如link,script,img,iframe等;
5、使用gzip壓縮內(nèi)容
Gzip壓縮所有可能的文件類型以來減少文件體積
6、把CSS放到頂部
實(shí)現(xiàn)頁面有秩序地加載,這對于擁有較多內(nèi)容的頁面和網(wǎng)速較慢的用戶來說更為重要,同時(shí),HTML規(guī)范清楚指出樣式表要放包含在頁面的區(qū)域內(nèi);
7、把JS放到底部
HTTP/1.1 規(guī)范建議,瀏覽器每個(gè)主機(jī)名的并行下載內(nèi)容不超過兩個(gè),而問題在于腳本阻止了頁面的平行下載,即便是主機(jī)名不相同
8、避免使用CSS表達(dá)式
頁面顯示和縮放,滾動、乃至移動鼠標(biāo)時(shí),CSS表達(dá)式的計(jì)算頻率是我們要關(guān)注的??梢钥紤]一次性的表達(dá)式或者使用事件句柄來代替CSS表達(dá)式。
9、將CSS和JS放到外部文件中
我們需要權(quán)衡內(nèi)置代碼帶來的HTTP請求減少與通過使用外部文件進(jìn)行緩存帶來的好處的折中點(diǎn)。
10、減少DNS查找次數(shù)
我們需要權(quán)衡減少 DNS查找次數(shù)和保持較高程度并行下載兩者之間的關(guān)系。
11、精簡CSS和JS
目的就是減少下載的文件體積,可考慮壓縮工具JSMin和YUI Compressor。
12、避免跳轉(zhuǎn)
為了確保“后退”按鈕可以正確地使用,使用標(biāo)準(zhǔn)的 3XXHTTP狀態(tài)代碼;同域中注意避免反斜杠 “/” 的跳轉(zhuǎn);
跨域使用 Alias或者 mod_rewirte建立 CNAME(保存一個(gè)域名和另外一個(gè)域名之間關(guān)系的DNS記錄)
13、剔除重復(fù)的JS和CSS
重復(fù)調(diào)用腳本,除了增加額外的HTTP請求外,多次運(yùn)算也會浪費(fèi)時(shí)間。在IE和Firefox中不管腳本是否可緩存,它們都存在重復(fù)運(yùn)算JavaScript的問題。
14、配置ETags
Entitytags(ETags)(實(shí)體標(biāo)簽)是web服務(wù)器和瀏覽器用于判斷瀏覽器緩存中的內(nèi)容和服務(wù)器中的原始內(nèi)容是否匹配的一種機(jī)制(“實(shí)體”就是所說的“內(nèi)容”,包括圖片、腳本、樣式表等),是比last-modifieddate更更加靈活的機(jī)制,單位時(shí)間內(nèi)文件被修過多次,Etag可以綜合Inode(文件的索引節(jié)點(diǎn)(inode)數(shù)),MTime(修改時(shí)間)和Size來精準(zhǔn)的進(jìn)行判斷,避開UNIX記錄MTime只能精確到秒的問題。服務(wù)器集群使用,可取后兩個(gè)參數(shù)。使用ETags減少Web應(yīng)用帶寬和負(fù)載。
15、使AJAX可緩存
利用時(shí)間戳,更精巧的實(shí)現(xiàn)響應(yīng)可緩存與服務(wù)器數(shù)據(jù)同步更新。
16、盡早刷新輸出緩沖
尤其對于css,js文件的并行下載更有意義
17、使用GET來完成AJAX請求
當(dāng)使用XMLHttpRequest時(shí),瀏覽器中的POST方法是一個(gè)“兩步走”的過程:首先發(fā)送文件頭,然后才發(fā)送數(shù)據(jù)。在url小于2K時(shí)使用GET獲取數(shù)據(jù)時(shí)更加有意義。
18、延遲加載
確定頁面運(yùn)行正常后,再加載腳本來實(shí)現(xiàn)如拖放和動畫,或者是隱藏部分的內(nèi)容以及折疊內(nèi)容等。
19、預(yù)加載
關(guān)注下無條件加載,有條件加載和有預(yù)期的加載。
20、減少DOM元素個(gè)數(shù)
使用更適合或者在語意是更貼切的標(biāo)簽,要考慮大量DOM元素中循環(huán)的性能開銷。
21、根據(jù)域名劃分頁面內(nèi)容
很顯然, 是最大限度地實(shí)現(xiàn)平行下載
22、盡量減少iframe的個(gè)數(shù)
考慮即使內(nèi)容為空,加載也需要時(shí)間,會阻止頁面加載,沒有語意,注意iframe相對于其他DOM元素高出1-2個(gè)數(shù)量級的開銷,它會在典型方式下阻塞onload事件,IE和Firefox中主頁面樣式表會阻塞它的下載。
23、避免404
HTTP請求時(shí)間消耗是很大的,有些站點(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í)行。
24、減少Cookie的大小
去除不必要的coockie
使coockie體積盡量小以減少對用戶響應(yīng)的影響
注意在適應(yīng)級別的域名上設(shè)置coockie以便使子域名不受影響
設(shè)置合理的過期時(shí)間。較早地Expire時(shí)間和不要過早去清除coockie,都會改善用戶的響應(yīng)時(shí)間。
25、使用無cookie的域
確定對于靜態(tài)內(nèi)容的請求是無coockie的請求。創(chuàng)建一個(gè)子域名并用他來存放所有靜態(tài)內(nèi)容。
26、減少DOM訪問
緩存已經(jīng)訪問過的有關(guān)元素
線下更新完節(jié)點(diǎn)之后再將它們添加到文檔樹中
避免使用JavaScript來修改頁面布局
27、開發(fā)智能事件處理程序
有時(shí)候我們會感覺到頁面反應(yīng)遲鈍,這是因?yàn)镈OM樹元素中附加了過多的事件句柄并且些事件句病被頻繁地觸發(fā)。這就是為什么說使用eventdelegation(事件代理)是一種好方法了。如果你在一個(gè)div中有10個(gè)按鈕,你只需要在div上附加一次事件句柄就可以了,而不用去為每一個(gè)按鈕增加一個(gè)句柄。事件冒泡時(shí)你可以捕捉到事件并判斷出是哪個(gè)事件發(fā)出的。
你同樣也不用為了操作DOM樹而等待onload事件的發(fā)生。你需要做的就是等待樹結(jié)構(gòu)中你要訪問的元素出現(xiàn)。你也不用等待所有圖像都加載完畢。
你可能會希望用DOMContentLoaded事件來代替 事件應(yīng)用程序中的onAvailable方法。
28、用代替@import
在IE中,頁面底部@import和使用作用是一樣的,因此最好不要使用它。
29、避免使用濾鏡
完全避免使用AlphaImageLoader的最好方法就是使用PNG8格式來代替,這種格式能在IE中很好地工作。如果你確實(shí)需要使用 AlphaImageLoader,請使用下劃線_filter又使之對IE7以上版本的用戶無效。
30、優(yōu)化圖像
嘗試把GIF格式轉(zhuǎn)換成PNG格式,看看是否節(jié)省空間。在所有的PNG圖片上運(yùn)行pngcrush(或者其它PNG優(yōu)化工具)
31、優(yōu)化CSS Spirite
在Spirite中水平排列你的圖片,垂直排列會稍稍增加文件大??;
Spirite中把顏色較近的組合在一起可以降低顏色數(shù),理想狀況是低于256色以便適用PNG8格式;
便于移動,不要在Spirite的圖像中間留有較大空隙。這雖然不大會增加文件大小但對于用戶代理來說它需要更少的內(nèi)存來把圖片解壓為像素地圖。 100×100的圖片為1萬像素,而1000×1000就是100萬像素。
32、不要在HTML中縮放圖像——須權(quán)衡
不要為了在HTML中設(shè)置長寬而使用比實(shí)際需要大的圖片。如果你需要:
那么你的圖片(mycat.jpg)就應(yīng)該是100×100像素而不是把一個(gè)500×500像素的圖片縮小使用。這里在下文有更有趣的分析。
33、favicon.ico要小而且可緩存
favicon.ico是位于服務(wù)器根目錄下的一個(gè)圖片文件。它是必定存在的,因?yàn)榧词鼓悴魂P(guān)心它是否有用,瀏覽器也會對它發(fā)出請求,因此最好不要返回一 個(gè)404 NotFound的響應(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。
34、保持單個(gè)內(nèi)容小于25K
因?yàn)閕Phone不能緩存大于25K的文件。注意這里指的是解壓縮后的大小。由于單純gizp壓縮可能達(dá)不要求,因此精簡文件就顯得十分重 要。
35、打包組件成復(fù)合文本
頁面內(nèi)容打包成復(fù)合文本就如同帶有多附件的Email,它能夠使你在一個(gè)HTTP請求中取得多個(gè)組件(切記:HTTP請求是很奢侈的)。當(dāng)你使用這條規(guī) 則時(shí),首先要確定用戶代理是否支持(iPhone就不支持)。
1、 使用json作為數(shù)據(jù)的交換格式
Json在瀏覽器解析的效率至少高于XML一個(gè)數(shù)量級,高級瀏覽器中內(nèi)置的有生成和解析json的方法,IE6中要用額外的方法(http://json.org),不要用eval,容易引發(fā)性能和安全問題。
2、 盡可能對images和table設(shè)定寬高值
針對Yslow的不要在HTML中縮放圖像——第33條,有人會誤解為不要對圖片加寬高值,其實(shí)這條建議本身的意思是不要為了獲取一個(gè)特定大小的圖片,而去強(qiáng)行通過設(shè)置寬高值拉伸或者壓縮一個(gè)既有的圖片。建議是另存一張符合尺寸的圖片替代。
對圖片和table是設(shè)定寬高,是考慮到如果瀏覽器能立刻知道圖片或者tables的寬高,它就能夠直接呈現(xiàn)頁面而不需要通過計(jì)算元素大小后重繪,而且即便是圖片損毀而沒有展現(xiàn),也不會進(jìn)而破壞了頁面本來的布局。
有一些應(yīng)用場景需要注意:
3、 拆離內(nèi)容塊
盡量用div取代tables,或者將tables打破成嵌套層次深的結(jié)構(gòu);
避免用這樣的嵌套
采用下面的或者div重構(gòu):
4、 高效的CSS書寫規(guī)則
眾所周知,CSS選擇符是從右向左進(jìn)行匹配的。
通常一個(gè)圖片列表的的小模塊
為了代碼上縮進(jìn)后內(nèi)層的整潔性,我們html有可能這樣寫之外,更喜歡看這樣的css寫法:
.box{border:1px solid #ccc } .box .hd{border-bottom:1px solid #ccc } .box .hd h3{color:#515151} .box .bd{color:#404040 } .box .bd ul{margin-left:10px} .box .bd ul li{border-bottom:1px dashed #f1f1f1} .box .bd ul li a{text-decoration:none} .box .bd ul li a:hover{text-decoration:underline} .box .bd ul li a img{border:1px solid #ccc} .box .bd ul li p{text-align:left;} .box .bd ul li p strong{color:#ff6600}
其實(shí)寫到這里,問題已經(jīng)顯而易見了。深達(dá)五層抑或六層的嵌套,同時(shí)右邊的選擇符都是采用標(biāo)簽,在滿足我們視覺平整與代碼結(jié)構(gòu)系統(tǒng)化的時(shí)候,付出的是性能的代價(jià)。
不做進(jìn)一步的代碼書寫方式的探討,受個(gè)人習(xí)慣與應(yīng)用場景影響。這里對css選擇符按照開銷從小到大的順序梳理一下:
參考《高性能網(wǎng)站建設(shè)-進(jìn)階指南》,有如下建議:
還要注意到,即便是頁面加載后,當(dāng)頁面被觸發(fā)引起回流(reflow)的時(shí)候,低效的選擇符依然會引發(fā)更高的開銷,顯然這對于用戶是不佳的體驗(yàn)。
在網(wǎng)站性能優(yōu)化的路上,是不會有終點(diǎn)的,這也是前端工程師永不會妥協(xié)的地方。
想看到更牛P的優(yōu)化建議么,請移步這里來關(guān)注李牧童鞋的分享:
作者:瓜瓜 | 發(fā)布: (編輯)kent.zhu | 時(shí)間:2011-07-18 23:36:22文字大?。?a href="javascript:fsmaller();" id="fsmaller" class="fsizeDisabled">- +