作移動web頁面,受移動網絡網速和終端性能影響,咱們常常要關注首屏內容展現時間(如下簡稱首屏時間)這個指標,它衡量着咱們的頁面是否能在用戶耐心消磨完以前展現出來,很大程度影響着用戶的使用滿意度。css
咱們常常要先問本身:頁面是怎麼加載數據?html
A:加載完靜態資源後經過ajax請求去後臺獲取數據,數據回來後渲染內容web
在每一個點打上一個時間戳,首屏時間 = 點8 – 點1;ajax
B:使用後臺直出,返回的html已經帶上內容了chrome
此時首屏時間 = 點4 – 點1。瀏覽器
注:1. 打了這麼多個點,是由於當咱們收集到首屏時間以後,要去分析究竟是哪一段是性能瓶頸,哪一段還有優化空間,因此咱們須要收集 點2 – 點一、點3 – 點1 ……這些時間以做分析;性能優化
2. 打點1咱們通常是在html文件head標籤的開頭打個時間戳;服務器
3. 在css文件加載前通常沒有別的加載處理,因此打點1和打點2通常能夠合併。網絡
到此咱們就收集到首屏相關各類數據,能夠作各類針對性優化。Wait!在你大刀闊斧優化前,你要了解一些細節,它們有利於你作更準確的分析和更細緻的優化。dom
JsEndTime – JsStartTime = js文件的加載時間,對嗎?
不對!明顯地,這個等式忽略了js的執行時間。js執行代碼是須要花費時間的,特別是作一些複雜的計算或頻繁的dom操做,這個執行時間有時會達到幾百毫秒。
那麼,JsEndTime – JsStartTime = js文件的加載執行時間?
依然不對!由於CSS文件的加載執行帶來了干擾。以爲很奇怪對吧,別急,咱們來作個試驗:咱們找一個demo頁面,在chrome裏面打開,而後啓動控制檯,模擬低網速,讓文件加載時間比較久:
先在正常狀況下收集 JsEndTime – JsStartTime 的時間,而後使用fiddler阻塞某一條css請求幾秒鐘:
而後再恢復請求,拿到此時的 JsEndTime – JsStartTime 結果,會發現第一次的時間是幾百毫秒將近1s,而第二次的時間低於100ms甚至接近爲0(個人示例,時間視讀者具體的js文件決定),二者的差距很是明顯。
這是什麼原理?這就是咱們常說的」加載是並行的,執行是串行的「的結果。html開始加載的時候,瀏覽器會將頁面外聯的css文件和js文件並行加載,若是一個文件還沒回來,它後面的代碼是不會執行的。剛剛咱們的demo,咱們阻塞了css文件幾秒,此時js文件由於並行已經加載回來,但因爲css文件阻塞住,因此後面 JsStartTime 的賦值語句是不執行的!當咱們放開阻塞,此時纔會運行到 JsStartTime 的賦值、js文件的解析、JsEndTime的賦值,因爲大頭時間加載早已完成,因此 JsEndTime 和 JsStartTime 的差值很是小。
知道這個有何用?
固然,那兩個打點留着仍是能夠作分析用的。
前半部分的結論在細節1裏面已經證實,由於瀏覽器的執行是串行的。這說明,咱們負責渲染內容的js代碼要等到它前面全部的js文件加載執行完纔會執行,即便那些代碼跟渲染無關的代碼如數據上報:
然後半部分的結論很好驗證,咱們在負責渲染的js文件後面外聯一個別的js文件並把它阻塞住,你會發現渲染相關的js不論是動態拉取新的js文件、拉取渲染相關內容都一切正常,頁面內容順利渲染出來,它們的執行並不須要等被阻塞的這個文件。
知道這個有何用?
(注:我的以爲這是全文最重要的兩點結論,由於我正在作首屏優化^-^)
打點1通常寫在html裏head標籤的最前面,時常有朋友拿直出時的 點4 – 點1 的時間和非直出時 點8 – 點1 的時候作對比,來講明直出優化了多少多少毫秒,我倒以爲不必定。要知道直出的狀況html文件包含渲染後的內容和dom節點,文件大小通常比非直出大,有時甚至大個幾十K都有,那我以爲要說明直出優化了多少就要把html的加載時間考慮進去了。那上面的計算方法是否考慮上html的加載時間?
那就要看html文件的返回頭是否包含chunk:
若是包含這個返回頭,那html文件是邊返回邊解析的,此時上面的計算方法是合理的。若是不包含這個頭,則html文件是整一個返回來後纔開始解析,此時上面的計算方法就少算了html的加載時間,也就不夠精準。這個返回頭是由後臺控制的。
知道這個有何用?
咱們有時會用 domContentLoaded 事件代替 onload 事件,在頁面準備好的時候作一些處理。然而要知道,domContentLoaded裏面的dom不止包含咱們常說的普通dom節點,還包括script節點。
試驗一下,咱們將頁面裏面外聯的一個js文件阻塞住一段時間再放開,咱們看下chrome控制檯:
很明顯,js文件的加載時間會影響這個事件的觸發事件。那js代碼的解析時間會不會影響?咱們在最後一個外聯js文件後面打了一個點,它的時間是:
因此js文件加載執行會影響domContentLoaded事件的執行時機。
知道這個有何用?
研究首屏時間和資源加載是一件挺有意思的事情,你們利用好chrome控制檯(特別是裏面的network標籤)以及fiddler能夠挖掘出不少有趣的小細節小結論。別覺得這是在沒事找事,理解好這些對你們作首屏性能優化、定位由於js文件執行順序錯亂致使報錯等場景是很是有好處的。因此發現什麼記得與我共享哈~