這篇文章主要介紹了JavaScript關(guān)于提高網(wǎng)站性能的幾點(diǎn)建議(一)的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
近在學(xué)習(xí)《高性能網(wǎng)站建設(shè)指南》這本書,本文算是一個(gè)學(xué)習(xí)筆記,將學(xué)到的東西進(jìn)行整理一下,方便后面查看。
性能黃金法則(Performance Golden Rule)解釋了只有10%~20%的最終用戶響應(yīng)時(shí)間花在接受所請求的用戶HTML文檔上,剩余的80%~90%時(shí)間花在為HTML文檔所引用的所有組件(圖片、腳本、樣式表等)進(jìn)行的HTTP請求上,最終用戶響應(yīng)時(shí)間花費(fèi)在頁面組件上
——Steve Sounders
1 文件合并(減少HTTP請求數(shù)量)
CSS Sprites
利用css sprites將網(wǎng)站用到的圖片合并成一張圖片,通過background-position、width、height控制背景圖位置來使用某一個(gè)圖標(biāo),這種方式可以將多個(gè)圖片請求縮減為一次,生成css sprites的工具也很多,grunt和gulp中都有相關(guān)的插件,CssGaga也不錯(cuò)。
合并js和css
和精靈圖一樣,合并css和js文件也是減少HTTP請求很重要的方式,對css文件的合并目前來說沒有什么爭議,但是對于當(dāng)前js模塊化盛行,將所有js文件合并成一個(gè)文件,仿佛是一種倒退。正確的方式是遵守編譯型語言的模式,保持js的模塊化,在生成過程中只對初始請求用到的js文件生成目標(biāo)文件。
2 使用內(nèi)容發(fā)布網(wǎng)絡(luò)(減少HTTP請求時(shí)間)
HTTP請求時(shí)間另一個(gè)影響因素是你與網(wǎng)站web服務(wù)器所處的距離,顯然距離越遠(yuǎn),請求所需的時(shí)間也越久,通過CDN可以大大改善這一點(diǎn)。
CDN是分布在多個(gè)不同地理位置的web服務(wù)器,用于更加有效的向用戶發(fā)布內(nèi)容。CDN最主要的功能是給終端用戶存放靜態(tài)文件,另外也提供下載、安全服務(wù)等功能。
3 設(shè)置瀏覽器緩存(避免重復(fù)HTTP請求)
使用Expire/Cache-control
瀏覽器通過使用緩存可以避免每次都進(jìn)行重復(fù)的請求,HTTP 1.0和HTTP1.1分別有不同的緩存實(shí)現(xiàn)方式,Expires(1.0)和Cache-control(1.1)。Web服務(wù)器通過expires告訴客戶端在指定的時(shí)間內(nèi),都使用該文件的緩存副本,不再向服務(wù)端重復(fù)發(fā)出請求,例如:
Expires: Thu, 01 Dec 2016 16:00:00 GMT (GMT格式)
這個(gè)設(shè)置意味著截止到2016年12月1日,都可以使用該緩存副本,無需再發(fā)出請求。
Expires這種通過截止日期的方式,存在一個(gè)限制:要求客戶端和服務(wù)端時(shí)鐘嚴(yán)格同步,而HTTP 1.1引入的Cache-Control通過指定一個(gè)以秒為單位的時(shí)間指定緩存日期,則不存該限制,例如:
Cache-Control: max-age=31536000
這個(gè)設(shè)置意味緩存時(shí)間為一年,推薦使用Cache-Control,但是在支持HTTP 1.1的情況下,另外要注意的一點(diǎn):Cache-Control和Expire同時(shí)存在時(shí),Cache-Control具有更高的優(yōu)先級。
配置或移除ETag
使用Expire/Cache-Control可以避免第二次訪問時(shí),使用本地緩存避免重復(fù)HTTP請求,提高網(wǎng)站速度。然而,在用戶點(diǎn)擊了瀏覽器刷新或者在expire已過期的情況下,仍然會(huì)向服務(wù)端發(fā)出HTTP GET請求,而此時(shí)如果該文件并沒有發(fā)生變化,服務(wù)端不會(huì)返回整個(gè)文件而是會(huì)返回304 Not Modified狀態(tài)碼。
服務(wù)端判斷該文件是否發(fā)生變化的依據(jù)有兩個(gè):Last-Modified(最新修改日期)和ETag(實(shí)體標(biāo)簽);
ETag(Entity Tags)是在HTTP 1.1引入的,與Last-Modified同時(shí)存在時(shí)要有更高的優(yōu)先級。服務(wù)端通過對比客戶端發(fā)來的ETag(If-None-Match)和當(dāng)前ETag,若相同返回304 Not Modifed,否則返回整個(gè)文件以及200 OK。
ETag存在一個(gè)問題:當(dāng)瀏覽器向一個(gè)服務(wù)器發(fā)送GET請求原始組件,之后又向另一臺服務(wù)器請求該組件時(shí),ETag是不匹配的,當(dāng)然,如果你的網(wǎng)站寄宿在一臺服務(wù)器上不存在這個(gè)問題,而現(xiàn)在很多網(wǎng)站使用多臺服務(wù)器,ETag的存在就大大降低驗(yàn)證有效性的成功率。
存在這個(gè)問題是時(shí)的解決辦法是對ETag進(jìn)行配置,移除服務(wù)器innode值只保留修改時(shí)間戳和大小作為ETag值,或者直接移除ETag,使用Last-Modified來驗(yàn)證文件有效性。
4 壓縮組件(減小HTTP請求大小)
通過對HTTP傳輸?shù)奈募M(jìn)行壓縮減小HTTP請求的大小,提高請求速度,GZIP是目前最常用也是最有效的壓縮方式。
然而,并非所有的資源文件都需要壓縮,壓縮的成本包括服務(wù)端需要花費(fèi)CPU周期進(jìn)行壓縮,而客戶端也需要對壓縮文件進(jìn)行解壓縮,必須結(jié)合自己網(wǎng)站進(jìn)行權(quán)衡?,F(xiàn)在絕大多數(shù)網(wǎng)站都對其HTML文檔進(jìn)行壓縮,部分網(wǎng)站選擇對js、css進(jìn)行壓縮,幾乎沒有網(wǎng)站對圖片、PDF等文件進(jìn)行GZIP壓縮,原因在于這些文件是已經(jīng)被壓縮過的,采用HTTP壓縮已經(jīng)被過壓縮的東西并不能使它更小。事實(shí)上,添加標(biāo)頭,壓縮字典,并校驗(yàn)響應(yīng)體實(shí)際上使它變得更大,而且還浪費(fèi)了CPU。
如何對網(wǎng)站開啟GZIP,需要在所使用的web服務(wù)器(IIS、Nginx、Apache等)中進(jìn)行設(shè)置。
5 CSS文件放在首部
將CSS文件放在首部和放在尾部,并不影響HTTP請求,因此從請求時(shí)間上來講是一致的,然而從用戶體驗(yàn)的角度,將CSS文件放在首部,會(huì)獲得更好的用戶體驗(yàn)。
原因在于瀏覽器是從上到下依次解析html文檔,將CSS文件置于頭部,頁面會(huì)首先對CSS文件發(fā)出請求,隨后加載DOM樹并對其進(jìn)行渲染,頁面會(huì)逐步呈現(xiàn)在用戶面前。
而與之相反,如果將CSS文件放置在尾部,頁面加載完整DOM之后請求CSS文件,然后對整個(gè)DOM樹渲染并呈現(xiàn)給用戶,從用戶的角度,在css文件沒有請求完成之前,整個(gè)頁面是出于白屏狀態(tài)的,白屏是瀏覽器的一種行為,David Hyatt對其的解釋是這樣的
在樣式樹沒有完全加載之前,渲染dom樹就是一種浪費(fèi),因?yàn)樵跇邮綐浼虞d完成之后會(huì)再次渲染,出現(xiàn)FOUC(無樣式內(nèi)容閃爍)問題。
另外要注意的一點(diǎn),使用link而不是@import引入css樣式表,使用@import引入的樣式即使寫在首部,也會(huì)在文檔最后加載。
6 JS文件放在尾部
HTTP請求是并行的,不同瀏覽器并行下載的數(shù)目也不一樣(2、4、或者8個(gè)),并行下載提高了HTTP請求的速度。而將JS文件放在首部,不僅會(huì)阻塞后面文件的下載而且會(huì)阻塞頁面的渲染。
為什么會(huì)這樣呢?原因有兩個(gè):
JS文件中可能存在document.write修改頁面的內(nèi)容,因此頁面會(huì)在腳本執(zhí)行完成之后才可使渲染。
不同JS文件不管大小如何,可能存在依賴關(guān)系,因此必須按照順序進(jìn)行執(zhí)行,因此在加載腳本的時(shí)候并行下載是禁止的。
所以,最好的方式是講js文件放置在尾部,等頁面所有可視化組件加載完成之后再進(jìn)行請求,提高用戶體驗(yàn)。
以上所述是小編給大家介紹的JavaScript關(guān)于提高網(wǎng)站性能的幾點(diǎn)建議(一),希望對大家有所幫助