經過 chrome 瀏覽器的開發者工具能夠直觀的看到,圖中藍色的線和藍色的字使用不一樣的表現形式表示 DOMContentLoaded 這個事件觸發的時間。chrome
咱們先來思考一個問題,如何衡量一個網頁的加載速度?瀏覽器
在平常生活中,不少時候由於網絡緣由咱們並不須要等待網頁上的全部內容都加載完畢,而是隻須要加載主要內容便可,好比你打開這篇博客時,可能並不須要等待全部圖片都加載完成,而是看到博客的正文就能夠正常閱讀。也就是說,用戶有時候只須要在空白的網頁上看見內容就能夠,而不須要等待全部內容都加載出來。服務器
那麼如何衡量「計算這個網頁從空白到出現內容所花費的時間」呢?HTML5 規範已經幫咱們完成相應的工做,即當一個 HTML 文檔被加載和解析完成後,DOMContentLoaded 事件便會被觸發。
瀏覽器向服務器請求到 HTML 文檔後便開始解析(其產物是 DOM),到這裏 HTML 文檔就能夠說是被加載和解析完成,同時若是有 CSS 文件則會根據 CSS 生成 CSSOM,而後再合併 DOM 和 CSSOM 生成渲染樹,至此咱們已經知道全部節點的樣式,下面便根據這些節點以及樣式計算它們在瀏覽器中確切的大小和位置(即佈局階段),最後獲得以上這些信息後,就能夠把節點繪製到瀏覽器上。網絡
下面咱們要加入考慮 JavaScript:JavaScript 能夠阻塞 DOM 的生成,也就是說當瀏覽器在解析 HTML 文檔時,若是遇到(同步)腳本則中止解析,先去加載腳本並執行,執行結束後繼續解析 HTML 文檔。async
當 HTML 文檔被解析時若是遇到 defer 腳本,則在後臺加載腳本,文檔解析過程不中斷,等待文檔解析結束以後,defer 腳本執行。工具
另外,defer 腳本的執行順序與定義時的位置有關。佈局
若是 script 標籤中包含 defer,那麼這一塊腳本將不會影響 HTML 文檔的解析,而是等到 HTML 解析完成後纔會執行,而 DOMContentLoaded 只有在 defer 腳本執行結束後纔會被觸發。HTML 文檔解析不受影響,等 DOM 構建完成以後 defer 腳本執行,但腳本執行以前須要等待 CSSOM 構建完成,在 DOM & CSSOM 構建完畢,defer 腳本執行完成以後,DOMContentLoaded 事件觸發。spa
當 HTML 文檔被解析時若是遇到 async 腳本,則在後臺加載腳本,文檔解析過程不中斷,腳本加載完成後,文檔中止解析並執行腳本,執行結束後文檔繼續解析。3d
當腳本下載完後當即執行,執行順序不肯定。事件
若是 script 標籤中包含 async,則 HTML 文檔構建不受影響,解析完畢後 DOMContentLoaded 觸發,而不須要等待 async 腳本執行、樣式表加載等。