1.盡量減少HTTP請求數(shù)
合并文件(css,js文件)
使用雪碧圖
行內(nèi)圖片(dataURL模式)
2.減少DNS查找
把組件分散在2到4個主機(jī)名下,這是同時減少DNS查找和允許高并發(fā)下載的這種方案。
3.避免重定向
4.讓ajax可緩存
5.延遲加載組件
6.預(yù)加載組件
無條件預(yù)加載——盡快加載
條件性預(yù)加載——預(yù)判用戶即將進(jìn)行的操作,進(jìn)行加載
提前預(yù)加載——在推出新設(shè)計之前加載一些組件
7.減少DOM元素的數(shù)量
語義化標(biāo)記
DOM元素的數(shù)量很容易測試,只需要在Firebug的控制臺里輸入:document.getElementsByTagName('*').length
8.跨域分離組件
分離組件可以最大化并行下載,但要確保只用不超過2-4個域,因為存在DNS查找的代價。例如,可以把HTML和動態(tài)內(nèi)容部署在www.example.org,而把靜態(tài)組件分離到static1.example.org和static2.example.org。
9.盡量少用iframe
用iframe可以把一個HTML文檔插到父文檔里,重要的是明白iframe是如何工作的并高效使用它。
<iframe>的優(yōu)點(diǎn):
- 引入緩慢的第三方內(nèi)容,比如標(biāo)志和廣告。
- 安全沙箱
- 并行下載腳本
<iframe>的缺點(diǎn)- 代價昂貴,即使是空白的iframe
- 阻塞頁面加載
- 非語義
10.杜絕404
HTTP請求代價高昂,完全沒有必要用一個HTTP請求去獲取一個無用的響應(yīng)(比如404 Not Found),只會拖慢用戶體驗而沒有任何好處。
css
11.避免使用CSS表達(dá)式
用CSS表達(dá)式動態(tài)設(shè)置CSS屬性,是一種強(qiáng)大又危險的方式。從IE5開始支持,但從IE8起就不推薦使用了。例如,可以用CSS表達(dá)式把背景顏色設(shè)置成按小時交替的:
background-color: expression( (new Date()).getHours()%2 ? "#B8D4FF" : "#F08A00" );
12.選擇<link>舍棄@import
13.避免使用濾鏡
14.把樣式表放在頂部
js
15.去除重復(fù)腳本
重復(fù)腳本會創(chuàng)建不必要的HTTP請求,執(zhí)行無用的JavaScript代碼,從而影響頁面性能。
16.盡量減少DOM訪問
用js去訪問DOM元素是很慢的,所以,為了讓頁面反應(yīng)更迅速,應(yīng)該:
- 緩存已經(jīng)訪問過的元素的索引
- 先“離線”更新節(jié)點(diǎn),再把它們添到DOM樹上
- 避免使用JavaScript修復(fù)布局問題
17.用智能的事件處理器
有時候感覺頁面反應(yīng)不夠靈敏,是因為有太多頻繁執(zhí)行的時間處理器被添加到了DOM樹的不同元素上,這就是推薦使用事件委托的原因。
18.把腳本放在底部
javaScript,css
19.把javaScript和css放到外面
html文檔中的行內(nèi)javaScript和css在每次請求該html文檔的時候都會重新下載。
20.壓縮javaScript和css文件
圖片
21.優(yōu)化圖片
22.優(yōu)化css Sprite
- 在Sprite圖片中橫向排列一般都比縱向排列的最終文件小
- 組合Sprite圖片中的相似顏色可以保持低色數(shù),最理想的是256色以下PNG8格式
- “對移動端友好”,不要在Sprite圖片中留下太大的空隙。雖然不會在很大程度上影響圖片文件的大小,但這樣做可以節(jié)省用戶代理把圖片解壓成像素映射時消耗的內(nèi)存。100×100的圖片是1萬個像素,而1000×1000的圖片就是100萬個像素了。
23.不要用HTML縮放圖爿
不要因為在HTML中可以設(shè)置寬高而使用本不需要的大圖。如果需要
<img width="100" height="100" src="mycat.jpg" alt="My Cat" />,那么圖片本身(mycat.jpg)應(yīng)該是100100px的,而不是去縮小500500px圖片。
24.用小的可以緩存的favicon.ico(收藏夾圖標(biāo))
favicon.ico是放在服務(wù)器根目錄的圖片,它會帶來一堆麻煩,因為你即使不管它,瀏覽器也會自動請求它,所以最好不要給一個404 Not Found相應(yīng)。而且只要在同一個服務(wù)器上,每次請求它時都會發(fā)送cookie,此外這個圖片還會干擾下載順序,例如在IE中,當(dāng)你在onload中請求額外組件時,將會先下載favicon。
所以為了緩解favicon.ico的缺點(diǎn),應(yīng)該確保:
- 足夠小,最好在1K以下
- 設(shè)置合適的有效期HTTP頭(以后如果想換的化就不能重命名了),把偶小氣設(shè)置為幾個月后一般比較安全,可以通過檢查當(dāng)前favicon.ico的最后修改日期來確保變更能讓瀏覽器知道。
cookie
25.給Cookie減肥
使用cookie的原因有很多,比如授權(quán)和個性化。HTTP頭中cookie信息在web服務(wù)器和瀏覽器之間交換。重要的是保證cookie盡可能的小,以最小化對用戶響應(yīng)時間的影響。
- 清除不必要的cookie
- 保證cookie盡可能小,以最小化對用戶響應(yīng)時間的影響
- 注意給cookie設(shè)置合適的域級別,以免影響其它子域
- 設(shè)置合適的有效期,更早的有效期或者none可以更快的刪除cookie,提高用戶響應(yīng)時間
26.把組件放在不含cookie的域下
當(dāng)瀏覽器發(fā)送對靜態(tài)圖像的請求時,cookie也會一起發(fā)送,而服務(wù)器根本不需要這些cookie。所以它們只會造成沒有意義的網(wǎng)絡(luò)通信量,應(yīng)該確保對靜態(tài)組件的請求不含cookie??梢詣?chuàng)建一個子域,把所有的靜態(tài)組件都部署在那兒。
如果域名是www.example.org,可以把靜態(tài)組件部署到static.example.org。然而,如果已經(jīng)在頂級域example.org或者www.example.org設(shè)置了cookie,那么所有對static.example.org的請求都會含有這些cookie。這時候可以再買一個新域名,把所有的靜態(tài)組件部署上去,并保持這個新域名不含cookie。Yahoo!用的是yimg.com,YouTube是ytimg.com,Amazon是images-amazon.com等等。
把靜態(tài)組件部署在不含cookie的域下還有一個好處是有些代理可能會拒絕緩存帶cookie的組件。有一點(diǎn)需要注意:如果不知道應(yīng)該用example.org還是www.example.org作為主頁,可以考慮一下cookie的影響。省略www的話,就只能把cookie寫到*.example.org,所以因為性能原因最好用www子域,并且把cookie寫到這個子域下。
移動端
27.保證所有組件都小于25K
28.把組件打包到一個復(fù)合文檔里
服務(wù)器
29.Gzip組件
前端工程師可以想辦法明顯地縮短通過網(wǎng)絡(luò)傳輸HTTP請求和響應(yīng)的時間。毫無疑問,終端用戶的帶寬速度,網(wǎng)絡(luò)服務(wù)商,對等交換點(diǎn)的距離等等,都是開發(fā)團(tuán)隊所無法控制的。但還有別的能夠影響響應(yīng)時間的因素,壓縮可以通過減少HTTP響應(yīng)的大小來縮短響應(yīng)時間。
從HTTP/1.1開始,web客戶端就有了支持壓縮的Accept-Encoding HTTP請求頭。
Accept-Encoding: gzip, deflate
如果web服務(wù)器看到這個請求頭,它就會用客戶端列出的一種方式來壓縮響應(yīng)。web服務(wù)器通過Content-Encoding相應(yīng)頭來通知客戶端。
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ā)送另一個請求。
31.設(shè)置Etags
32.對ajax使用GET請求
瀏覽器的POST請求是通過一個兩步的過程來實(shí)現(xiàn)的:先發(fā)送HTTP頭,在發(fā)送數(shù)據(jù)。所以最好用GET請求,它只需要發(fā)送一個TCP報文(除非cookie特別多)。IE的URL長度最大值是2K,所以如果要發(fā)送的數(shù)據(jù)超過2K就無法使用GET了。
POST請求的一個有趣的副作用是實(shí)際上沒有發(fā)送任何數(shù)據(jù),就像GET請求一樣。正如HTTP說明文檔中描述的,GET請求是用來檢索信息的。所以它的語義只是用GET請求來請求數(shù)據(jù),而不是用來發(fā)送需要存儲到服務(wù)器的數(shù)據(jù)。
33.盡早清空緩沖區(qū)
當(dāng)用戶請求一個頁面時,服務(wù)器需要用大約200到500毫秒來組裝HTML頁面,在這期間,瀏覽器閑等著數(shù)據(jù)到達(dá)。PHP中有一個flush()函數(shù),允許給瀏覽器發(fā)送一部分已經(jīng)準(zhǔn)備完畢的HTML響應(yīng),以便瀏覽器可以在后臺準(zhǔn)備剩余部分的同時開始獲取組件,好處主要體現(xiàn)在很忙的后臺或者很“輕”的前端頁面上(P.S. 也就是說,響應(yīng)時耗主要在后臺方面時最能體現(xiàn)優(yōu)勢)。
較理想的清空緩沖區(qū)的位置是HEAD后面,因為HTML的HEAD部分通常更容易生成,并且允許引入任何CSS和JavaScript文件,這樣就可以讓瀏覽器在后臺還在處理的時候就開始并行獲取組件。
例如:
<pre style="margin: 0px; padding: 0px; white-space: pre-wrap; word-wrap: break-word; font-family: "Courier New" !important; font-size: 12px !important;"> ... <!-- css, js -->
</head>
<?php flush(); ?>
<body>
... <!-- content --></pre>
34.使用CDN(內(nèi)容分發(fā)網(wǎng)絡(luò))
35.添上Expires或者Cache-Control HTTP頭
這條規(guī)則有兩個方面:
對于靜態(tài)組件:通過設(shè)置一個遙遠(yuǎn)的將來時間作為Expires來實(shí)現(xiàn)永不失效
多余動態(tài)組件:用合適的Cache-ControlHTTP頭來讓瀏覽器進(jìn)行條件性的請求
網(wǎng)頁設(shè)計越來越豐富,這意味著頁面里有更多的腳本,圖片和Flash。站點(diǎn)的新訪客可能還是不得不提交幾個HTTP請求,但通過使用有效期能讓組件變得可緩存,這避免了在接下來的瀏覽過程中不必要的HTTP請求。有效期HTTP頭通常被用在圖片上,但它們應(yīng)該用在所有組件上,包括腳本、樣式和Flash組件。
瀏覽器(和代理)用緩存來減少HTTP請求的數(shù)目和大小,讓頁面能夠更快加載。web服務(wù)器通過有效期HTTP響應(yīng)頭來告訴客戶端,頁面的各個組件應(yīng)該被緩存多久。用一個遙遠(yuǎn)的將來時間做有效期,告訴瀏覽器這個響應(yīng)在2010年4月15日前不會改變。Expires: Thu, 15 Apr 2010 20:00:00 GMT
如果你用的是Apache服務(wù)器,用ExpiresDefault指令來設(shè)置相對于當(dāng)前日期的有效期。下面的例子設(shè)置了從請求時間起10年的有效期:ExpiresDefault "access plus 10 years"