引言問題 test.js和background.jpg是並行下載,還是test.js先下載後執行完成後再下載background.jpg??? 這樣呢? 我會在文章最後給出解答。 之前都只瞭解了大概,沒有深入地做測試驗證他人所說,這次一定要整的明明白白。 瀏覽器的渲染引擎 script 值得一提的是 ...
引言問題
<img src="background.jpg">
<script src="test.js"></script>
test.js和background.jpg是並行下載,還是test.js先下載後執行完成後再下載background.jpg???
<script src="test.js"></script>
<img src="background.jpg">
這樣呢?
我會在文章最後給出解答。
之前都只瞭解了大概,沒有深入地做測試驗證他人所說,這次一定要整的明明白白。
瀏覽器的渲染引擎
script
值得一提的是js外部腳本的載入方式
沒有defer、async屬性時
值得註意的是對於多個script標簽,比如
<script src="a.js"></script> <script src="b.js"></script>
有defer屬性,並行下載完後等到頁面解析完後執行
有async屬性,也就是並行下載完後就執行
此外這裡還有他人總結的一份筆記,寫的挺好的。
題目解答
回到之前的題目上,按照阮一峰博客解釋,傳統情況下,應該是這樣的:
1.當script在img標簽前時,js會阻塞img的下載,js文件會先下載,下載後執行,執行完成後再下載img.
因為解析到script標簽時,頁面會暫停解析,將網頁渲染的控制權會交給js引擎,js文件下載完成後執行,執行完成後控制權交還渲染引擎,恢復往下解析,然後解析到img標簽就下載img
<script src="test.js"></script> <img src="background.jpg">
測試結果(藍色為下載時間)
2.當img在script標簽前時,img文件是非同步下載,不會阻塞js的下載,會和js一起並行下載
因為link,img等都是非同步下載。
<img src="background.jpg"> <script src="test.js"></script>
然而今天我去問了下大佬,大佬說,
下載腳本不阻塞,執行才會阻塞,只是阻塞渲染
傳統結果是這樣的,但是現代瀏覽器會嘗試所有的資源都儘快的載入,測試時可以看到並行的結果
然後我又去測試了下,發現不管是img在前還是js在前都有出現並行下載的情況,也證實了大佬的說法
總結
瀏覽器實際渲染過程:
1.解析整個html文檔(HTML代碼解析為DOM,CSS代碼解析為CSSOM(CSS Object Model))
2.解析過程中遇到外部腳本和資源就非同步下載,下載好後緩存。
3.將dom和cssom構建成渲染樹(解析文檔的過程就已經開始構建渲染樹了)--------渲染樹構建完成則觸發DOMContentLoaded事件
4.根據渲染樹渲染頁面(計算佈局、繪製頁面)
5.渲染過程中遇到script節點(不含defer和async)時,暫停渲染,執行js腳本。
如果是非同步腳本,則不會阻塞渲染:
- 如果腳本帶有defer屬性,則不會執行,需要等到頁面渲染完成再執行。
- 如果腳本帶有async屬性,則下載完後就執行,不需要等到頁面渲染完成再執行,並且不會暫停渲染。(因此不要在非同步腳本中操縱dom)
6.繼續渲染直到完成。--------頁面渲染完成則觸發load事件
以上過程並非嚴格按照順序執行,第一步還沒完成,第二第三步可能就已經開始了。第二第三步還沒完成,第四步就已經開始了
感謝大佬的指導@簫秦
參考了阮一峰的瀏覽器環境概述:http://javascript.ruanyifeng.com/bom/engine.html