1.沒有 或`async` 瀏覽器遇到腳本的時候會暫停渲染並立即載入執行腳本(外部腳本),“立即”指的是在渲染該 script 標簽之下的文檔元素之前,也就是說不等待後續載入的文檔元素,讀到就載入並執行。因此如果將JS腳本放置在head的話會產生 ,並且腳本當中對於DOM的操作也會出現報錯,因為還沒 ...
1.沒有defer
或async
瀏覽器遇到腳本的時候會暫停渲染並立即載入執行腳本(外部腳本),“立即”指的是在渲染該 script 標簽之下的文檔元素之前,也就是說不等待後續載入的文檔元素,讀到就載入並執行。因此如果將JS腳本放置在head的話會產生阻塞
,並且腳本當中對於DOM的操作也會出現報錯,因為還沒有生成。
放在body底部的JS腳本的執行順序是按照在文檔中的先後順序執行的,而不是按照下載下的順序
2.有async
過程如下:
1.瀏覽器開始解析網頁
2.解析過程中,發現帶有async屬性的script標簽
3.瀏覽器繼續往下解析 HTML 網頁,同時並行下載外部腳本
4.腳本下載完成,瀏覽器暫停解析網頁,開始執行下載的腳本
5.腳本執行完畢,瀏覽器恢復解析網頁
async
腳本執行順序是下載的順序
3.有defer
過程如下:
1.瀏覽器開始解析網頁
2.解析過程中,發現帶有defer屬性的腳本元素
3.瀏覽器繼續往下解析網頁,同時並行下載腳本元素載入的外部腳本
4.瀏覽器完成解析網頁,此時再回過頭執行已經下載完成的腳本
defer
腳本執行順序是出現的先後順序
4.defer
還是async
?
兩者之間的選擇則是看腳本之間是否有依賴關係,有依賴的話應當要保證執行順序,應當使用defer
沒有依賴的話使用async
,同時使用的話defer
失效。要註意的是兩者都不應該使用document.write
,這個導致整個頁面被清除。
瀏覽器完整過程是先解析渲染HTML,當遇到腳本文件的時候則執行腳本文件,等待腳本文件執行完畢才繼續解析html,因此會產生阻塞頁面的情況,因此最好將腳本放在body底部,當瀏覽器遇到標有defer的時候則會下載該腳本,同是繼續解析html,然後等到dom解析完畢之後才解析defer腳本,而如果遇到async腳本的時候同樣是下載該腳本同是繼續解析html,當anync下載完畢之後,而html尚未解析完畢,也會先解析async腳本,等待async腳本解析完畢之後才繼續解析html。
詳細的過程對比參考下圖: