雅虎军规——前端优化的35条建议
無論是在工作中,還是在面試中,web前端性能的優(yōu)化都是很重要的,那么我們進(jìn)行優(yōu)化需要從哪些方面入手呢?yohoo關(guān)于性能優(yōu)化的35條的軍規(guī),web2.0的設(shè)計(jì)與視覺,用戶越來越注重用戶體驗(yàn),但用戶體驗(yàn)的前提就是網(wǎng)站的訪問速度,對(duì)于一個(gè)大型網(wǎng)站的yahoo來說,處理性能優(yōu)化是不可缺少的,他是怎么制定性能優(yōu)化呢,相比很多朋友都想了解下,YaHoo把性能優(yōu)化作為他們不可觸犯的軍規(guī),具體怎樣優(yōu)化呢,且看他們的優(yōu)化方案。
80%-90%的終端響應(yīng)時(shí)間是花費(fèi)在下載頁面中的圖片,樣式表,腳本,flash等;雅虎軍規(guī)可以分類7大類35條,包括內(nèi)容、服務(wù)器、CSS、JS、Cookie、圖片、移動(dòng)應(yīng)用。現(xiàn)在說一些常用的規(guī)則。
1、盡可能減少HTTP請(qǐng)求數(shù)
那么什么是HTTP請(qǐng)求呢?——從客戶端到服務(wù)器端的請(qǐng)求消息,包括消息首行中,對(duì)資源的請(qǐng)求方法資源的標(biāo)識(shí)符及使用的協(xié)議。通俗一點(diǎn)說就是:當(dāng)你打開網(wǎng)頁的時(shí)候,你所看到的文字、圖片、多媒體等等,這一切內(nèi)容,都是從服務(wù)器獲取的。每一個(gè)內(nèi)容的獲取,就是一個(gè)HTTP請(qǐng)求。
合并文件:把所有的腳本放到一個(gè)文件中來減少HTTP請(qǐng)求。比如合并項(xiàng)目中的JS、CSS。
CSS Sprites是減少圖片請(qǐng)求數(shù)量的首選方式。把背景圖片都整合到一張圖片中,然后用CSS的background-image和background-position屬性來定位要顯示的部分。
減少頁面的HTTP請(qǐng)求數(shù)是個(gè)起點(diǎn),這是提升站點(diǎn)首次訪問速度的重要指導(dǎo)原則。
了解這個(gè)只是對(duì)于我們網(wǎng)站設(shè)計(jì)和優(yōu)化有何啟示呢?
由于DNS查找是需要時(shí)間的,而且它們通常都是只緩存一定的時(shí)間,所以應(yīng)該盡可能地減少DNS查找的次數(shù)。
減少DNS查找次數(shù),最理想的方法就是將所有的內(nèi)容資源都放在同一個(gè)域(Domain)下面,這樣訪問整個(gè)網(wǎng)站就只需要進(jìn)行一次DNS查找,這樣可以提高性能。
但理想總歸是理想,上面的理想做法會(huì)帶來另外一個(gè)問題,就是由于這些資源都在同一個(gè)域,而HTTP /1.1 中推薦客戶端針對(duì)每個(gè)域只有一定數(shù)量的并行度(它的建議是2),那么就會(huì)出現(xiàn)下載資源時(shí)的排隊(duì)現(xiàn)象,這樣就會(huì)降低性能。
所以,折衷的做法是:建議在一個(gè)網(wǎng)站里面使用至少2個(gè)域,但不多于4個(gè)域來提供資源。我認(rèn)為這條建議是很合理的,也值得我們?cè)陧?xiàng)目實(shí)踐中去應(yīng)用。
2、減少DNS查詢
域名系統(tǒng)建立了主機(jī)名和IP地址間的映射,就像電話簿上人名和號(hào)碼的映射一樣。當(dāng)你在瀏覽器輸入www.yahoo.com的時(shí)候,瀏覽器就會(huì)聯(lián)系DNS解析器返回服務(wù)器的IP地址。DNS是有成本的,它需要20到120毫秒去查找給定主機(jī)名的IP地址。在DNS查找完成之前,瀏覽器無法從主機(jī)名下載任何東西。
大多數(shù)瀏覽器有獨(dú)立于操作系統(tǒng)的自己的cache。只要瀏覽器在自己的cache里還保留著這條記錄,它就不會(huì)向操作系統(tǒng)查詢DNS。
IE默認(rèn)緩存DNS查找30分鐘,寫在DnsCacheTimeout注冊(cè)表設(shè)置中。Firefox緩存1分鐘,可以用network.dnsCacheExpiration配置項(xiàng)設(shè)置。Chrome同樣緩存一分鐘。
那么時(shí)間長短有什么不同呢?
緩存時(shí)間長:減少DNS的重復(fù)查找,節(jié)省時(shí)間
緩存時(shí)間短:及時(shí)的檢測網(wǎng)站服務(wù)器的變化,保證正確性。
3、避免重定向
重定向用301(永久性重定向)和302(臨時(shí)重定向)狀態(tài)碼,下面是一個(gè)有301狀態(tài)碼的HTTP頭:
HTTP/1.1 301 Moved PermanentlyLocation: http://example.com/newuriContent-Type: text/html牢記重定向會(huì)拖慢用戶體驗(yàn),在用戶和HTML文檔之間插入重定向會(huì)延遲頁面上的所有東西,頁面無法渲染,組件也無法開始下載,直到HTML文檔被送達(dá)瀏覽器。
有一種常見的極其浪費(fèi)資源的重定向,而且web開發(fā)人員一般都意識(shí)不到這一點(diǎn),就是URL尾部缺少一個(gè)斜線的時(shí)候。例如,跳轉(zhuǎn)到http://astrology.yahoo.com/astrology會(huì)返回一個(gè)重定向到http://astrology.yahoo.com/astrology/的301響應(yīng)(注意添在尾部的斜線)。在Apache中可以用Alias,mod_rewrite或者DirectorySlash指令來取消不必要的重定向。
如果你的網(wǎng)站使用了301重定向,搜索引擎在爬網(wǎng)的時(shí)候,會(huì)進(jìn)行分析。當(dāng)發(fā)現(xiàn)是301重定向的時(shí)候,它會(huì)記錄下新的地址,刪除原來的舊地址。也就是說301使得搜索引擎變得智能。
如果你使用的是302,搜索引擎會(huì)先找到舊地址,再去跳新的地址。
4、使AJAX緩存
利用時(shí)間戳,更精巧的實(shí)現(xiàn)響應(yīng)可緩存與服務(wù)器數(shù)據(jù)同步更新。
5、為文件頭指定Expires或Cache-Control,使內(nèi)容具有緩存性。
區(qū)分靜態(tài)內(nèi)容和動(dòng)態(tài)內(nèi)容,避免以后頁面訪問中不必要的HTTP請(qǐng)求。
6、使用CDN(內(nèi)容分發(fā)網(wǎng)絡(luò))
這里可以關(guān)注CDN的三類實(shí)現(xiàn):鏡像、高速緩存、專線,以及智能路由器和負(fù)載均衡;
7、啟用Gzip壓縮
GZIP,即網(wǎng)頁壓縮,是由WEB服務(wù)器和瀏覽器之間共同遵守的協(xié)議,也就是說WEB服務(wù)器和瀏覽器都必須支持該技術(shù),而現(xiàn)在主流的瀏覽器都是支 持的,包括IE、FireFox、谷歌瀏覽器、Opera 等。常見的WEB服務(wù)器有Apache 和IIS 等。雙方的協(xié)商過程如下:
(1)首先瀏覽器請(qǐng)求某個(gè)URL 地址,并在請(qǐng)求的頭 (head) 中設(shè)置屬性accept-encoding值為gzip、deflate,表明瀏覽器支持gzip和deflate這兩種壓縮方式。
(2)WEB服務(wù)器接收到請(qǐng)求后判斷瀏覽器是否支持壓縮,如果支持就傳送壓縮后的響應(yīng)內(nèi)容,否則傳送不經(jīng)過壓縮的內(nèi)容;
(3)瀏覽器獲取響應(yīng)內(nèi)容后,判斷內(nèi)容是否被壓縮,如果是則解壓縮,然后顯示響應(yīng)頁面的內(nèi)容。
GZIP壓縮的比率往往在3到10倍,也就是本來90k大小的頁面,采用壓縮后實(shí)際傳輸?shù)膬?nèi)容大小只有28至30K大小,這可以大大節(jié)省服務(wù)器的 網(wǎng)絡(luò)帶寬,同時(shí)如果應(yīng)用程序的響應(yīng)足夠快時(shí),網(wǎng)站的速度瓶頸就轉(zhuǎn)到了網(wǎng)絡(luò)的傳輸速度上,因此內(nèi)容壓縮后就可以大大的提升頁面的瀏覽速度。
在實(shí)際應(yīng)用中,并不需要對(duì)網(wǎng)站所有文件都進(jìn)行壓縮,只需要對(duì)靜態(tài)文件進(jìn)行壓縮就可以了,包括js、css及html文件。對(duì)其他文件進(jìn)行壓縮并不 會(huì)對(duì)WEB性能有太多的改觀,并且對(duì)網(wǎng)站開啟GZIP功能是需要犧牲部分服務(wù)器性能的。
8、將css放在頁面最上面
關(guān)注性能的前端工程師想讓頁面逐步渲染。也就是說,我們想讓瀏覽器盡快顯示已有內(nèi)容,這在頁面上有一大堆內(nèi)容或者用戶網(wǎng)速很慢時(shí)顯得尤為重要。
9、將script放下頁面最下面
腳本會(huì)阻塞并行下載,HTTP/1.1官方文檔建議瀏覽器每個(gè)主機(jī)名下并行下載的組件數(shù)不要超過兩個(gè),如果圖片來自多個(gè)主機(jī)名,并行下載的數(shù)量就可以超過兩個(gè)。如果腳本正在下載,瀏覽器就不開始任何其它下載任務(wù),即使是在不同主機(jī)名下的。
再比如,如果引入的js文件有個(gè)死循環(huán)或者執(zhí)行時(shí)間很長的腳本,如果將這個(gè)腳本放到頭部,那么瀏覽器會(huì)一直加載這個(gè)腳本而停止對(duì)網(wǎng)頁的渲染,會(huì)造成頁面一直空白,用戶一直等待渲染的問題。這將造成很差的用戶體驗(yàn)。如果將此腳本放到頁面最下面,頁面的HTML、CSS將先呈現(xiàn)給用戶,用戶會(huì)因?yàn)轫撁嫣崆凹虞d而覺得速度更快。
有時(shí)候,并不容易把腳本移動(dòng)到底部。舉個(gè)例子,如果腳本是用document.write插入到頁面內(nèi)容中的,就沒辦法再往下移了。還可能存在作用域問題,在多數(shù)情況下,這些問題都是可以解決的。
一個(gè)常見的建議是用推遲(deferred)腳本,有DEFER屬性的腳本意味著不能含有document.write,并且提示瀏覽器告訴他們可以繼續(xù)渲染。不幸的是,Firefox不支持DEFER屬性。在IE中,腳本可能被推遲,但不盡如人意。如果腳本可以推遲,我們就可以把它放到頁面底部,頁面就可以更快地載入。
10、把JavaScript和CSS放到外面
很多性能原則都是關(guān)于如何管理外部組件的,然而,在這些顧慮出現(xiàn)之前你應(yīng)該問一個(gè)更基礎(chǔ)的問題:應(yīng)該把JavaScript和CSS放到外部文件中還是直接寫在頁面里?
實(shí)際上,用外部文件可以讓頁面更快,因?yàn)镴avaScript和CSS文件會(huì)被緩存在瀏覽器。HTML文檔中的行內(nèi)JavaScript和CSS在每次請(qǐng)求該HTML文檔的時(shí)候都會(huì)重新下載。這樣做減少了所需的HTTP請(qǐng)求數(shù),但增加了HTML文檔的大小。另一方面,如果JavaScript和CSS在外部文件中,并且已經(jīng)被瀏覽器緩存起來了,那么我們就成功地把HTML文檔變小了,而且還沒有增加HTTP請(qǐng)求數(shù)。
所以是否將這兩種文件放到外面不是絕對(duì)的,應(yīng)該視情況而定。如果這是一個(gè)不常訪問的頁面,或者這個(gè)頁面的css、js非常少,只有幾行,那么完全沒有必要放到外面。
11、移除重復(fù)的腳本
頁面含有重復(fù)的腳本文件會(huì)影響性能,這可能和你想象的不一樣。在對(duì)美國前10大web站點(diǎn)的評(píng)審中,發(fā)現(xiàn)只有2個(gè)站點(diǎn)含有重復(fù)腳本。兩個(gè)主要原因增加了在單一頁面中出現(xiàn)重復(fù)腳本的幾率:團(tuán)隊(duì)大小和腳本數(shù)量。在這種情況下,重復(fù)腳本會(huì)創(chuàng)建不必要的HTTP請(qǐng)求,執(zhí)行無用的JavaScript代碼,而影響頁面性能。
IE會(huì)產(chǎn)生不必要的HTTP請(qǐng)求,而Firefox不會(huì)。在IE中,如果一個(gè)不可緩存的外部腳本被頁面引入了兩次,它會(huì)在頁面加載時(shí)產(chǎn)生兩個(gè)HTTP請(qǐng)求。即使腳本是可緩存的,在用戶重新加載頁面時(shí)也會(huì)產(chǎn)生額外的HTTP請(qǐng)求。
除了產(chǎn)生沒有意義的HTTP請(qǐng)求之外,多次對(duì)腳本求值也會(huì)浪費(fèi)時(shí)間。因?yàn)闊o論腳本是否可緩存,在Firefox和IE中都會(huì)執(zhí)行冗余的JavaScript代碼。
避免不小心把相同腳本引入兩次的一種方法就是在模版系統(tǒng)中實(shí)現(xiàn)腳本管理模塊。典型的腳本引入方法就是在HTML頁面中用SCRIPT標(biāo)簽:
<script type="text/javascript" src="menu_1.0.17.js"></script>12、不要用HTML縮放圖片
不要因?yàn)樵贖TML中可以設(shè)置寬高而使用本不需要的大圖。如果需要
<img width="100" height="100" src="mycat.jpg" alt="My Cat" />那么圖片本身(mycat.jpg)應(yīng)該是100x100px的,而不是去縮小500x500px的圖片。
13、減少cookie的大小
使用cookie的原因有很多,比如授權(quán)和個(gè)性化。HTTP頭中cookie信息在web服務(wù)器和瀏覽器之間交換。重要的是保證cookie盡可能的小,以最小化對(duì)用戶響應(yīng)時(shí)間的影響。
- 列表內(nèi)容
去除不必要的coockie
使coockie體積盡量小以減少對(duì)用戶響應(yīng)的影響
注意在適應(yīng)級(jí)別的域名上設(shè)置coockie以便使子域名不受影響
設(shè)置合理的過期時(shí)間。較早地Expire時(shí)間和不要過早去清除coockie,都會(huì)改善用戶的響應(yīng)時(shí)間。
14、避免圖片src屬性為空
Image with empty string src屬性是空字符串的圖片很常見,主要以兩種形式出現(xiàn):
straight HTML:
<img src=””>JavaScript:
var img = new Image(); img.src = “”;雅虎的團(tuán)隊(duì)指出,如果你將img的src留空,可能你的本意是暫時(shí)不要顯示任何圖片,但在不同的瀏覽器其實(shí)還是會(huì)有一些額外的請(qǐng)求發(fā)生。據(jù)我的觀察,現(xiàn)在的這些瀏覽器都不再發(fā)送額外的請(qǐng)求了。這也算是瀏覽器自身的改進(jìn)吧,為什么要對(duì)一個(gè)空白的img去發(fā)起額外的請(qǐng)求呢?
但既然以前早期的版本有可能發(fā)生這樣的事情,如果你無法確保你的用戶都使用最新的現(xiàn)代瀏覽器,那么請(qǐng)簡單地遵守這條原則:總是給img的src設(shè)置值,而且是一個(gè)合法的值。
作為開發(fā)者,我理解有的時(shí)候,你想將src留空的原因在于,頁面加載的時(shí)候,你想快速完全加載,這些圖片你可能想后期再根據(jù)實(shí)際情況再加載。如果真的是這樣,你應(yīng)該參考一下另外一個(gè)討論:優(yōu)化網(wǎng)站設(shè)計(jì)(十七):延遲或按需加載內(nèi)容。
或者很簡單地,你可以將初始圖片設(shè)置為一個(gè)很小的默認(rèn)圖片(這個(gè)圖片設(shè)置永不過期),而不是留空。
總結(jié)
以上是生活随笔為你收集整理的雅虎军规——前端优化的35条建议的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 一键实现前程无忧(51job)简历不停刷
- 下一篇: PMP 项目管理知识框架 - 引子