前端開發(fā)工程師必須關(guān)注的幾個(gè)性能指標(biāo)
關(guān)于頁面相應(yīng)時(shí)間,有一條著名的“2-5-8原則”。當(dāng)用戶訪問一個(gè)頁面:
在2秒內(nèi)得到響應(yīng)時(shí),會(huì)感覺系統(tǒng)響應(yīng)很快;
在2-5秒之間得到響應(yīng)時(shí),會(huì)感覺系統(tǒng)的響應(yīng)速度還可以;
在5-8秒以內(nèi)得到響應(yīng)時(shí),會(huì)感覺系統(tǒng)的響應(yīng)速度很慢,但可以接受;
而超過8秒后仍然無法得到響應(yīng)時(shí),用戶會(huì)感覺系統(tǒng)糟透了,進(jìn)而選擇離開這個(gè)站點(diǎn),或者發(fā)起第二次請(qǐng)求。
對(duì)于一個(gè)網(wǎng)站如果希望抓住用戶,網(wǎng)站的速度以及穩(wěn)定性是首當(dāng)其沖的。
從各式各樣的前端監(jiān)控平臺(tái)中,你都可以獲得頁面很多的性能指標(biāo)。本文將介紹幾個(gè)幾個(gè)比較關(guān)鍵的指標(biāo),并給出相應(yīng)的優(yōu)化思路。
開始渲染時(shí)間
該時(shí)間點(diǎn)表示瀏覽器開始繪制頁面,在此之前頁面都是白屏,所以也稱為白屏?xí)r間。
該時(shí)間點(diǎn)可用公式Time To Start Render = TTFB(Time To First Byte) + TTDD(Time To Document Download) + TTHE(Time To Head End)表示。其中TTFB表示瀏覽器發(fā)起請(qǐng)求到服務(wù)器返回***個(gè)字節(jié)的時(shí)間,TTDD表示從服務(wù)器加載HTML文檔的時(shí)間,TTHE表示文檔頭部解析完成所需要的時(shí)間。在高級(jí)瀏覽器中有對(duì)應(yīng)的屬性可以獲取該時(shí)間點(diǎn)。Chrome可通過chrome.loadTimes().firstPaintTime獲取,IE9+可以通過performance.timing.msFirstPaint獲取,在不支持的瀏覽器中可以根據(jù)上面公式通過獲取頭部資源加載完的時(shí)刻模擬獲取近似值。開始渲染時(shí)間越快,用戶就能更快的看見頁面。
對(duì)于該時(shí)間點(diǎn)的優(yōu)化有:
1)優(yōu)化服務(wù)器響應(yīng)時(shí)間,服務(wù)器端盡早輸出
2)減少html文件大小
3)減少頭部資源,腳本盡量放在body中
DOM Ready
該時(shí)間點(diǎn)表示dom解析已經(jīng)完成,資源還沒有加載完成, 這個(gè)時(shí)候用戶與頁面的交互已經(jīng)可用了。用公式TimeTo Dom Ready = TTSR(Time To Start Render) + TTDC(Time To Dom Created) + TTST(Time To Script)可以表示。TTSR上面已經(jīng)介紹過了,TTDC表示DOM樹創(chuàng)建所耗時(shí)間。TTST表示BODY中所有靜態(tài)腳本加載和執(zhí)行的時(shí)間。在高級(jí)瀏覽器中有DOMContentLoaded事件對(duì)應(yīng),MDN上有關(guān)DOMContentLoaded事件描述的文檔如下,
The DOMContentLoaded event is fired when the document has been completely loaded and parsed, without waiting for stylesheets, images, and subframes to finish loading (the load event can be used to detect a fully-loaded page).
詳細(xì)規(guī)范可以查看W3C的HTML5規(guī)范。從MDN文檔上可以看出該事件主要是指dom文檔加載解析完成,看上去很簡單,但是DOMContentLoaded事件的觸發(fā)與css,js息息相關(guān),現(xiàn)在有專門的名詞Critical Rendering Path(關(guān)鍵呈現(xiàn)路徑)來描述,在文章【關(guān)鍵呈現(xiàn)路徑】中詳細(xì)介紹了關(guān)鍵呈現(xiàn)路徑對(duì)DOMContentLoaded的影響。
在不支持DOMContentLoaded事件的瀏覽器中可以通過模擬獲取近似值,主要的模擬方法有:
1)低版本webkit內(nèi)核瀏覽器可以通過輪詢document.readyState來實(shí)現(xiàn)
2)ie中可通過setTimeout不斷調(diào)用documentElement的doScroll方法,直到其可用來實(shí)現(xiàn)
具體實(shí)現(xiàn)方法可以參考主流框架(jquery等)的實(shí)現(xiàn)。 DOM Ready時(shí)間點(diǎn)意味著用戶與頁面可以進(jìn)行交互了,因此越早越好,對(duì)于該時(shí)間點(diǎn)的優(yōu)化有:
1)減少dom結(jié)構(gòu)的復(fù)雜度,節(jié)點(diǎn)盡可能少,嵌套不要太深
2)優(yōu)化關(guān)鍵呈現(xiàn)路徑
首屏?xí)r間
該時(shí)間點(diǎn)表示用戶看到***屏頁面的時(shí)間,這個(gè)時(shí)間點(diǎn)很重要但是很難獲取,一般都只能通過模擬獲取一個(gè)近似時(shí)間。一般模擬方法有:
1)不斷獲取屏幕截圖,當(dāng)截圖不再變化時(shí),可以視為首屏?xí)r間??蓞⒖紈ebPagetest的Speed Index算法;
2)一般影響首屏的主要因素是圖片的加載,通過頁面加載完后判斷圖片是否在首屏內(nèi),找出加載最慢的一張即可視為首屏?xí)r間。當(dāng)然還需考慮其他細(xì)節(jié),具體可參考【7天打造前端性能監(jiān)控系統(tǒng)】
針對(duì)該時(shí)間點(diǎn)的優(yōu)化有:
1)頁面首屏的顯示盡量不要依賴于js代碼,js盡量放到domReady后執(zhí)行或加載
2)首屏外的圖片延遲加載
3)首屏結(jié)構(gòu)盡量簡單,首屏外的css可延遲加載
onload
該時(shí)間點(diǎn)是window.onload事件觸發(fā)的時(shí)間,表示原始文檔和所有引用的內(nèi)容已經(jīng)加載完成,用戶最明顯的感覺就是瀏覽器tab上loading狀態(tài)結(jié)束。
該時(shí)間點(diǎn)的優(yōu)化方式有:
1)減少資源的請(qǐng)求數(shù)和文件大小
2)將非初始化腳本放到onLoad之后執(zhí)行
3)無需同步的腳本異步加載
為了優(yōu)化整站性能,頁面onload的時(shí)候可以考慮做一些預(yù)加載,把其它頁面需要用到的資源預(yù)先加載進(jìn)來。