前端網(wǎng)頁提速的具體方法
前端網(wǎng)頁提速的具體方法先說說目標(biāo), 前端優(yōu)化的目標(biāo)是什么, 一個(gè)字:快. 兩個(gè)字:更快. 那么下面我們來看看慢的網(wǎng)頁將會(huì)給我們帶來什么:1. 慢的頁面可能會(huì)網(wǎng)站失去更多的用戶.2. 慢500ms 意味
前端網(wǎng)頁提速的具體方法
先說說目標(biāo), 前端優(yōu)化的目標(biāo)是什么, 一個(gè)字:快. 兩個(gè)字:更快. 那么下面我們來看看慢的網(wǎng)頁將會(huì)給我們帶來什么:
1. 慢的頁面可能會(huì)網(wǎng)站失去更多的用戶.
2. 慢500ms 意味著20的用戶將放棄訪問(google)
3. 慢100ms 意味著1的用戶將放棄交易(amazon)
4. 慢 ???ms 意味著??的用戶將放棄xx(your site)
所以我們的目標(biāo)很明確, 就是要網(wǎng)頁展現(xiàn)的速度更快. 方法如下:
0. 減少http 請(qǐng)求
我把它排在了第一點(diǎn), 為啥要在第一點(diǎn)呢, 很簡(jiǎn)單, 因?yàn)樗钪匾?
如何做呢. 一般來說, 我們從變化性上把數(shù)據(jù)分成兩種類型, 變和不變. 那么不變的數(shù)據(jù)可以緩存, 變化的數(shù)據(jù)不能緩存, 這是一個(gè)常識(shí), 也就是說要減少我們的http 請(qǐng)求次數(shù)這個(gè)目標(biāo)可以轉(zhuǎn)換成把數(shù)據(jù)分為變化和不變化兩個(gè)部分. 不變化的數(shù)據(jù)不需要再次請(qǐng)求, 這樣http 請(qǐng)求的次數(shù)就減少了, 下面我們分點(diǎn)來描述將數(shù)據(jù)分類的途徑.
1. 合并腳本文件
包括腳本, 樣式和圖片, 可以有選擇的把一些Js 和css 可以合并成一個(gè)文件, 一些圖片可以使用css sprites 技術(shù). 這樣做的原因是什么? 做過web 開發(fā)的人都知道,js 和css 基本是不變的, 是靜態(tài)文件, 圖片亦然. 那么不變的文件如果適當(dāng)?shù)暮喜⒃谝黄? 會(huì)有什么效果呢? 請(qǐng)求的次數(shù)
,從多次變成了一次. 這樣http 請(qǐng)求的次數(shù)就減少了. 當(dāng)時(shí)合并之后, 文件體積變大了, 會(huì)影響速度嗎? 答:肯定會(huì)啊, 不過這里是需要權(quán)衡的, 比如我100份靜態(tài)文件, 合并成10份還是合并成1份這就得看你得具體情況了.
2. 指定Expires 或者Cache-Control
對(duì)于靜態(tài)內(nèi)容:設(shè)置文件頭過期時(shí)間Expires 的值為“Never expire”(永不過期) 動(dòng)態(tài)頁面, 在代碼中添加cache-control, 表示多少時(shí)間之后過期, 如:
response.setHeader("Cache-Control", "max-age=3600");
如果使用了Expires 文件頭,當(dāng)頁面內(nèi)容改變時(shí)就必須改變內(nèi)容的文件名。通常是在文件內(nèi)容后加版本號(hào)
這一點(diǎn)在企業(yè)應(yīng)用的系統(tǒng)中也時(shí)有發(fā)生. 比如我們使用extjs 作為前端的技術(shù),400多k 啊, 每打開一個(gè)頁面都導(dǎo)入, 下載這個(gè)js, 夠無聊的. 那么童子們可能就要問了, 靜態(tài)文件為啥不用apache,lighttpd 等呢, 答, 用了又怎么樣, 不設(shè)expire 或者max-age 不是一樣要下載, 最好的方法是寫一個(gè)filter, 再filter 中判斷, 如果url 滿足一定的條件(比如符合配置文件中的正則表達(dá)式), 那么就設(shè)置一個(gè)max-age, 這樣就ok, 太簡(jiǎn)單了, 幾行代碼就可以搞定. 快哉.
3. 緩存Ajax 請(qǐng)求
緩存的方法同動(dòng)態(tài)頁面,ajax 請(qǐng)求需要使用get 方式,url 長(zhǎng)度為2k(ie)限制(post請(qǐng)求有兩個(gè)過程,1發(fā)送請(qǐng)求headers,2發(fā)送請(qǐng)求數(shù)據(jù), 根據(jù)http 規(guī)范,get 請(qǐng)求只會(huì)發(fā)送一個(gè)tcp 包).--------這一段話來自yahoo, 先不管其真假, 我們從另外一個(gè)方面來考慮一下為什么最好使用get 方式, 之前有一個(gè)項(xiàng)目的ajax 請(qǐng)求使用了post 方式, 后來發(fā)現(xiàn)經(jīng)常出錯(cuò), 而且拋出了squid 的錯(cuò)誤, 因?yàn)槲覀兊木W(wǎng)站使用了squid, 問題就出在這里了, 從http 協(xié)議上可以了解
,到,method=post是指把數(shù)據(jù)提交到服務(wù)器上去, 那么squid 的一個(gè)特性是不會(huì)緩存post 請(qǐng)求(事實(shí)上它確實(shí)不應(yīng)該緩存, 因?yàn)檫@樣會(huì)違反http 協(xié)議中的語義), 把a(bǔ)jax 請(qǐng)求改成get 方式之后, 一切恢復(fù)如常.
4. 移除重復(fù)的js
重復(fù)的js 導(dǎo)入也有可能導(dǎo)致ie 重新加載該腳本. 沒啥好說的, 照做.
5. 避免重定向
有一種經(jīng)常被網(wǎng)頁開發(fā)者忽略卻往往十分浪費(fèi)響應(yīng)時(shí)間的跳轉(zhuǎn)現(xiàn)象。這種現(xiàn)象發(fā)生在當(dāng)URL 本該有斜杠(/)卻被忽略掉時(shí)。這時(shí)候會(huì)返回一個(gè)301的狀態(tài)碼, 然后瀏覽器重新發(fā)起一次請(qǐng)求. 在企業(yè)應(yīng)用里, 重定向是我們?cè)谄髽I(yè)應(yīng)用中常用的技術(shù), 不過用在網(wǎng)站項(xiàng)目上, 您可要小心了, 因?yàn)槠胀ǖ闹囟ㄏ蚱鋵?shí)是server 在response header 中設(shè)置http status=302,瀏覽器收到之后, 判斷出是302, 會(huì)重新發(fā)送一個(gè)請(qǐng)求, 目標(biāo)地址是前一次返回中指定的地址. 在網(wǎng)站項(xiàng)目中如果可以不用重定向就別用吧. 如果您做企業(yè)應(yīng)用項(xiàng)目,ok, 關(guān)系不大, 您就放心的”定”吧.
6. 使用cdn
讓內(nèi)容更靠近用戶, 這有啥好說呢, 原理很簡(jiǎn)單, 就是根據(jù)用戶瀏覽器所在機(jī)器的ip 來判斷哪些服務(wù)器離用戶最近, 瀏覽器會(huì)再次去請(qǐng)求這些最近的機(jī)器. 一般的cdn 服務(wù)商是通過開發(fā)自己的dns server 來達(dá)到這個(gè)目的的. 不過這個(gè)是通常情況哦, 技術(shù)實(shí)力比較高, 或者場(chǎng)景比較特殊的公司會(huì)開發(fā)自己的cdn. 當(dāng)然不管怎么說, 使用cdn 肯定可以使頁面響應(yīng)更快(也包括音頻, 視頻, 圖片, 文本文件, 等等等等)
,7. 減小返回?cái)?shù)據(jù)的體積
(1) 使用gzip 壓縮返回?cái)?shù)據(jù)
Gzip 壓縮所有可能的文件類型是減少文件體積增加用戶體驗(yàn)的簡(jiǎn)單方法。比如本來400k 的文件, 壓縮一下之后只有50k-100k, 那么網(wǎng)絡(luò)的流量就立刻下來了, 壓縮的代價(jià)是服務(wù)器端要壓縮文件, 需要消耗cpu, 瀏覽器需要解壓文件, 也需要消耗cpu, 不過對(duì)于現(xiàn)代這么nb 的pc, 來說, 瀏覽器解壓一下數(shù)據(jù)帶來的cpu 消耗簡(jiǎn)直不值一提. 所以您就壓吧. 不過壓的時(shí)候要小心哦, 有的瀏覽器在特定場(chǎng)景下會(huì)出去一些小bug, 導(dǎo)致頁面不正常. 比如ie6在跨域的時(shí)候可能會(huì)有些小麻煩, 把這部分?jǐn)?shù)據(jù)的gzip 去掉就可以了.
(2) 最小化js 文件和css 文件
壓縮js 可以使用JSMin 或者YUI Compressor, 后者同時(shí)可以壓縮css, 這個(gè)也沒啥好說的, 照做吧.
(3) 將css 和js 獨(dú)立成外部文件
其實(shí)這一點(diǎn)也可以看成是區(qū)分不變數(shù)據(jù)和變化數(shù)據(jù). 很多人喜歡在頁面商寫很多很多的js 和css, 這些數(shù)據(jù)其實(shí)都是不會(huì)變化的數(shù)據(jù), 也就是說這些數(shù)據(jù)也是可以緩存在瀏覽器上的, 通過把它們獨(dú)立成外部文件, 可以把這些數(shù)據(jù)緩存起來. 這樣做看上去是增加的請(qǐng)求的次數(shù), 但是由于第一次請(qǐng)求之后該部分?jǐn)?shù)據(jù)已經(jīng)被緩存, 所以第二次就無需再請(qǐng)求后端, 減少了網(wǎng)絡(luò)帶寬的開銷.
8. 優(yōu)化Cookie
(1) 減小cookie 體積
能不放就別放吧, 為啥呀,cookie 就象鑰匙串, 只有出門和回家得時(shí)候才用, 但是一整天你都要
,帶在身上, 麻煩不.
(2) 合理設(shè)置Cookie 域
由于二級(jí)域名可以拿到一級(jí)域名得cookie, 那么如果, 而二級(jí)域名之間確不能相互共享cookie, 所以合理得設(shè)置cookie 得域名也可以避免無必要得帶寬浪費(fèi)和響應(yīng)速度得增加.
(3) 設(shè)置合理的cookie 過期時(shí)間
該過期就過期, 不要讓不必要的數(shù)據(jù)一直帶在身上走來走去.
(4) 使用域分離
為圖片或者其他靜態(tài)資源文件使用子域或者建立新的獨(dú)立域名(申請(qǐng)新的域名), 避免無必要的cookie 傳輸, 當(dāng)然也是要在有必要得情況下, 圖片類網(wǎng)站肯定有必要,javaeye 上得圖片并沒有使用域分離, 所以我們得cookie 其實(shí)會(huì)帶到壇子得圖片服務(wù)器上去, 每次請(qǐng)求圖片都是如此(不過還好, 壇子里沒有什么圖片, 所以這方面的浪費(fèi)不大).
(5) 小結(jié)
其實(shí)cookie 上得問題, 單詞請(qǐng)求看上去也不是什么大問題, 好像是無所謂得事情, 就那么幾十個(gè)byte, 至于嗎, 不過大家都聽說過水滴石穿, 繩鋸木斷的故事. 所以該做的, 我們還是要做, 正所謂, 勿以善小而不為, 勿以惡小而為之.
9. 優(yōu)化瀏覽器加載
(1)將css 放在頁面頂部加載
把樣式表放在文檔底部的問題是在包括Internet Explorer在內(nèi)的很多瀏覽器中這會(huì)中止內(nèi)容的有序呈現(xiàn)。瀏覽器中止呈現(xiàn)是為了避免樣式改變引起的頁面元素重繪。用戶不得不面對(duì)一個(gè)空白頁面。
HTML 規(guī)范清楚指出樣式表要放包含在頁面的
只能出現(xiàn)在文檔的