瀏覽器在解析 HTML 的時候秫舌,如果遇到一個沒有任何屬性的script標簽,就會暫停解析绣檬,先發(fā)送網絡請求獲取該 JS 腳本的代碼內容舅巷,然后讓 JS 引擎執(zhí)行該代碼,當代碼執(zhí)行完畢后恢復解析河咽。它不會等待后續(xù)加載的文檔元素钠右,讀取到就會開始加載和執(zhí)行,這樣就阻塞了后續(xù)文檔的加載忘蟹。
script 阻塞了瀏覽器對 HTML 的解析,如果獲取 JS 腳本的網絡請求遲遲得不到響應狠毯,或者 JS 腳本執(zhí)行時間過長褥芒,都會導致白屏嫡良,用戶看不到頁面內容寝受。
而 defer 和 async屬性都是去異步加載外部的JS腳本文件很澄,它們都不會阻塞頁面的解析甩苛,其區(qū)別如下:
1俏站、 執(zhí)行順序:
- 多個帶async屬性的標簽,不能保證加載的順序爱葵,完全依賴于網絡傳輸結果萌丈,誰先到執(zhí)行誰雷则;
- 多個帶defer屬性的標簽,按照在 HTML 中出現的順序執(zhí)行度迂;
2惭墓、 腳本是否并行執(zhí)行:
- async:后續(xù)文檔的加載和執(zhí)行 與 js腳本的加載 是并行進行的而姐,即異步執(zhí)行;
- defer:加載后續(xù)文檔的過程 和 js腳本的加載 (僅加載不執(zhí)行)是并行進行的(異步)钧萍,js腳本需要等到文檔所有元素解析完成之后才執(zhí)行风瘦,DOMContentLoaded事件觸發(fā)執(zhí)行之前公般。
3胡桨、是否阻塞解析html
- async:可能阻塞昧谊,也可能不阻塞
- defer: 不阻塞
async阻塞的場景:當瀏覽器遇到帶有 async 屬性的 script 時揽浙,請求該腳本的網絡請求是異步的意敛,不會阻塞瀏覽器解析 HTML膛虫,一旦網絡請求回來之后,如果此時 HTML 還沒有解析完撩独,瀏覽器會暫停解析综膀,先讓 JS 引擎執(zhí)行代碼局齿,執(zhí)行完畢后再進行解析。
async不阻塞的場景:如果在 JS 腳本請求回來之前讥此,HTML 已經解析完畢了萄喳,立即執(zhí)行 JS 代碼他巨,不存在阻塞問題
defer不阻塞的原因:獲取該腳本的網絡請求是異步的闻蛀,不會阻塞瀏覽器解析 HTML您市,一旦網絡請求回來之后,如果此時 HTML 還沒有解析完薪棒,瀏覽器不會暫停解析并執(zhí)行 JS 代碼,而是等待 HTML 解析完畢再執(zhí)行 JS 代碼
avaScript腳本延遲加載的方式有哪些棵介?
延遲加載就是等頁面加載完成之后再加載 JavaScript 文件邮辽。 js 延遲加載有助于提高頁面加載速度贸营。
- defer 屬性:
- async 屬性:
- 動態(tài)創(chuàng)建 DOM 方式:動態(tài)創(chuàng)建 DOM 標簽的方式,可以對文檔的加載事件進行監(jiān)聽揣云,當文檔加載完成后再動態(tài)的創(chuàng)建 script 標簽來引入 js 腳本冰啃。
- 使用 setTimeout 延遲方法:設置一個定時器來延遲加載js腳本文件
- 讓 JS 最后加載:將 js 腳本放在文檔的底部阎毅,來使 js 腳本盡可能的在最后來加載執(zhí)行。