性能測試網(wǎng)站www.webpagetest.org
1.盡量減少HTTP請求數(shù)
- 文件合并角溃,減少資源請求次數(shù)
- CSS Sprites缘挽,合并背景圖片
- 行內(nèi)圖片(base64)
2.減少DNS查找
減少不同主機名的數(shù)量同時也減少了頁面能夠并行下載的組件數(shù)量乳附,避免DNS查找削減了響應(yīng)時間,而減少并行下載數(shù)量卻增加了響應(yīng)時間赏参。我的原則是把組件分散在2到4個主機名下,這是同時減少DNS查找和允許高并發(fā)下載的折中方案韭脊。
3.避免重定向
有一種常見的極其浪費資源的重定向,而且web開發(fā)人員一般都意識不到這一點单旁,就是URL尾部缺少一個斜線的時候沪羔。例如,跳轉(zhuǎn)到http://astrology.yahoo.com/astrology會返回一個重定向到http://astrology.yahoo.com/astrology/的301響應(yīng)(注意添在尾部的斜線)象浑。在Apache中可以用Alias
蔫饰,mod_rewrite
或者DirectorySlash
指令來取消不必要的重定向。
4.讓Ajax可緩存
5.延遲加載組件
可以湊近看看頁面并問自己:什么才是一開始渲染頁面所必須的愉豺?其余內(nèi)容都可以等會兒篓吁。
JavaScript是分隔onload事件之前和之后的一個理想選擇。例如蚪拦,如果有JavaScript代碼和支持拖放以及動畫的庫杖剪,這些都可以先等會兒,因為拖放元素是在頁面最初渲染之后的驰贷。其它可以延遲加載的部分包括隱藏內(nèi)容(在某個交互動作之后才出現(xiàn)的內(nèi)容)和折疊的圖片盛嘿。
工具可幫你減輕工作量:YUI Image Loader可以延遲加載折疊的圖片,還有YUI Get utility是一種引入JS和CSS的簡單方法括袒。Yahoo!主頁就是一個例子次兆,可以打開Firebug的網(wǎng)絡(luò)面板仔細看看。
最好讓性能目標符合其它web開發(fā)最佳實踐箱熬,比如“漸進增強”类垦。如果客戶端支持JavaScript,可以提高用戶體驗城须,但必須確保頁面在不支持JavaScript時也能正常工作蚤认。所以,在確定頁面運行正常之后糕伐,可以用一些延遲加載腳本增強它砰琢,以支持一些拖放和動畫之類的華麗效果。
6.預(yù)加載組件
預(yù)加載可能看起來和延遲加載是相反的良瞧,但它其實有不同的目標陪汽。通過預(yù)加載組件可以充分利用瀏覽器空閑的時間來請求將來會用到的組件(圖片,樣式和腳本)褥蚯。用戶訪問下一頁的時候挚冤,大部分組件都已經(jīng)在緩存里了,所以在用戶看來頁面會加載得更快赞庶。
實際應(yīng)用中有以下幾種預(yù)加載的類型:
- 無條件預(yù)加載——盡快開始加載训挡,獲取一些額外的組件澳骤。google.com就是一個sprite圖片預(yù)加載的好例子,這個sprite圖片并不是google.com主頁需要的澜薄,而是搜索結(jié)果頁面上的內(nèi)容为肮。
- 條件性預(yù)加載——根據(jù)用戶操作猜測用戶將要跳轉(zhuǎn)到哪里并據(jù)此預(yù)加載。在search.yahoo.com的輸入框里鍵入內(nèi)容后肤京,可以看到那些額外組件是怎樣請求加載的颊艳。
- 提前預(yù)加載——在推出新設(shè)計之前預(yù)加載。經(jīng)常在重新設(shè)計之后會聽到:“這個新網(wǎng)站不錯忘分,但比以前更慢了”棋枕,一部分原因是用戶訪問先前的頁面都是有舊緩存的,但新的卻是一種空緩存狀態(tài)下的體驗饭庞〗溆疲可以通過在將要推出新設(shè)計之前預(yù)加載一些組件來減輕這種負面影響,老站可以利用瀏覽器空閑的時間來請求那些新站需要的圖片和腳本舟山。
7.減少DOM元素的數(shù)量
一個復(fù)雜的頁面意味著要下載更多的字節(jié)绸狐,而且用JavaScript訪問DOM也會更慢。舉個例子累盗,想要添加一個事件處理器的時候寒矿,循環(huán)遍歷頁面上的500個DOM元素和5000個DOM元素是有區(qū)別的。
大量的DOM元素是一種征兆——頁面上有些內(nèi)容無關(guān)的標記需要清理若债。正在用嵌套表格來布局嗎符相?還是為了修復(fù)布局問題而添了一堆的<div>
s?或許應(yīng)該用更好的語義化標記蠢琳。
YUI CSS utilities對布局有很大幫助:grids.css針對整體布局啊终,fonts.css和reset.css可以用來去除瀏覽器的默認格式。這是個開始清理和思考標記的好機會傲须,例如只在語義上有意義的時候使用<div>
蓝牲,而不是因為它能夠渲染一個新行。
DOM元素的數(shù)量很容易測試泰讽,只需要在Firebug的控制臺里輸入:
<pre style="margin: 0px; padding: 0px; white-space: pre-wrap; word-wrap: break-word; font-family: "Courier New" !important; font-size: 12px !important;">document.getElementsByTagName('*').length</pre>
那么多少DOM元素才算是太多呢例衍?可以參考其它類似的標記良好的頁面,例如Yahoo!主頁是一個相當繁忙的頁面已卸,但只有不到700個元素(HTML標簽)佛玄。
8.跨域分離組件
分離組件可以最大化并行下載,但要確保只用不超過2-4個域累澡,因為存在DNS查找的代價梦抢。例如,可以把HTML和動態(tài)內(nèi)容部署在www.example.org愧哟,而把靜態(tài)組件分離到static1.example.org和static2.example.org奥吩。
9.盡量少用iframe
10.杜絕404
11.避免使用CSS表達式
12.選擇<link>舍棄@import
13.避免使用濾鏡
IE專有的AlphaImageLoader濾鏡可以用來修復(fù)IE7之前的版本中半透明PNG圖片的問題具伍。在圖片加載過程中,這個濾鏡會阻塞渲染圈驼,卡住瀏覽器,還會增加內(nèi)存消耗而且是被應(yīng)用到每個元素的望几,而不是每個圖片绩脆,所以會存在一大堆問題。
最好的方法是干脆不要用AlphaImageLoader橄抹,而優(yōu)雅地降級到用在IE中支持性很好的PNG8圖片來代替靴迫。如果非要用AlphaImageLoader,應(yīng)該用下劃線hack:_filter來避免影響IE7及更高版本的用戶楼誓。
14.把樣式表放在頂部
腳本篇
15.去除重復(fù)腳本
16.盡量減少DOM訪問
用JavaScript訪問DOM元素是很慢的玉锌,所以,為了讓頁面反應(yīng)更迅速疟羹,應(yīng)該:
緩存已訪問過的元素的索引
先“離線”更新節(jié)點主守,再把它們添到DOM樹上
避免用JavaScript修復(fù)布局問題
17.用智能的事件處理器
有時候感覺頁面反映不夠靈敏,是因為有太多頻繁執(zhí)行的事件處理器被添加到了DOM樹的不同元素上榄融,這就是推薦使用事件委托的原因参淫。如果一個div里面有10個按鈕,應(yīng)該只給div容器添加一個事件處理器愧杯,而不是給每個按鈕都添加一個涎才。事件能夠冒泡,所以可以捕獲事件并得知哪個按鈕是事件源力九。
18.把腳本放在底部
腳本會阻塞并行下載耍铜,HTTP/1.1官方文檔建議瀏覽器每個主機名下并行下載的組件數(shù)不要超過兩個,如果圖片來自多個主機名跌前,并行下載的數(shù)量就可以超過兩個棕兼。如果腳本正在下載,瀏覽器就不開始任何其它下載任務(wù)舒萎,即使是在不同主機名下的程储。
有時候,并不容易把腳本移動到底部臂寝。舉個例子章鲤,如果腳本是用document.write插入到頁面內(nèi)容中的,就沒辦法再往下移了咆贬。還可能存在作用域問題败徊,在多數(shù)情況下,這些問題都是可以解決的掏缎。
一個常見的建議是用推遲(deferred)腳本皱蹦,有DEFER屬性的腳本意味著不能含有document.write煤杀,并且提示瀏覽器告訴他們可以繼續(xù)渲染。不幸的是沪哺,F(xiàn)irefox不支持DEFER屬性沈自。在IE中,腳本可能被推遲辜妓,但不盡如人意枯途。如果腳本可以推遲,我們就可以把它放到頁面底部籍滴,頁面就可以更快地載入酪夷。
19.把JavaScript和CSS放到外面
很多性能原則都是關(guān)于如何管理外部組件的,然而孽惰,在這些顧慮出現(xiàn)之前你應(yīng)該問一個更基礎(chǔ)的問題:應(yīng)該把JavaScript和CSS放到外部文件中還是直接寫在頁面里晚岭?
實際上,用外部文件可以讓頁面更快勋功,因為JavaScript和CSS文件會被緩存在瀏覽器坦报。HTML文檔中的行內(nèi)JavaScript和CSS在每次請求該HTML文檔的時候都會重新下載。這樣做減少了所需的HTTP請求數(shù)狂鞋,但增加了HTML文檔的大小燎竖。另一方面,如果JavaScript和CSS在外部文件中要销,并且已經(jīng)被瀏覽器緩存起來了构回,那么我們就成功地把HTML文檔變小了,而且還沒有增加HTTP請求數(shù)
20.壓縮JavaScript和CSS
21.優(yōu)化圖片
22.優(yōu)化CSS Sprite
23.不要用HTML縮放圖片
不要因為在HTML中可以設(shè)置寬高而使用本不需要的大圖疏咐。如果需要
1
<img width="100" height="100" src="mycat.jpg" alt="My Cat" />
那么圖片本身(mycat.jpg)應(yīng)該是100x100px的纤掸,而不是去縮小500x500px的圖片。
24.用小的可緩存的favicon.ico
25.給Cookie減肥
26.把組件放在不含cookie的域下
當瀏覽器發(fā)送對靜態(tài)圖像的請求時浑塞,cookie也會一起發(fā)送借跪,而服務(wù)器根本不需要這些cookie。所以它們只會造成沒有意義的網(wǎng)絡(luò)通信量酌壕,應(yīng)該確保對靜態(tài)組件的請求不含cookie掏愁。可以創(chuàng)建一個子域卵牍,把所有的靜態(tài)組件都部署在那兒果港。
移動端
27.保證所有組件都小于25K
這個限制是因為iPhone不能緩存大于25K的組件,注意這里指的是未壓縮的大小糊昙。這就是為什么縮減內(nèi)容本身也很重要辛掠,因為單純的gzip可能不夠。
28.把組件打包到一個復(fù)合文檔里
服務(wù)器
29.Gzip組件
前端工程師可以想辦法明顯地縮短通過網(wǎng)絡(luò)傳輸HTTP請求和響應(yīng)的時間。毫無疑問萝衩,終端用戶的帶寬速度回挽,網(wǎng)絡(luò)服務(wù)商,對等交換點的距離等等猩谊,都是開發(fā)團隊所無法控制的千劈。但還有別的能夠影響響應(yīng)時間的因素,壓縮可以通過減少HTTP響應(yīng)的大小來縮短響應(yīng)時間牌捷。
從HTTP/1.1開始队塘,web客戶端就有了支持壓縮的Accept-Encoding HTTP請求頭。
1
Accept-Encoding: gzip, deflate
如果web服務(wù)器看到這個請求頭宜鸯,它就會用客戶端列出的一種方式來壓縮響應(yīng)。web服務(wù)器通過Content-Encoding相應(yīng)頭來通知客戶端遮怜。
1
Content-Encoding: gzip
盡可能多地用gzip壓縮能夠給頁面減肥淋袖,這也是提升用戶體驗最簡單的方法。
30.避免圖片src屬性為空
Image with empty string src屬性是空字符串的圖片很常見锯梁,主要以兩種形式出現(xiàn):
straight HTML
<img src=””>
JavaScript
var img = new Image();
img.src = “”;
這兩種形式都會引起相同的問題:瀏覽器會向服務(wù)器發(fā)送另一個請求即碗。