引言問題
<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
