前言:
向HTML頁面中插入JavaScrip的主要方法,就是使用<script>標簽。主要探討<script>標簽的在HTML頁面的渲染機制。對應的業務場景:從js的加載機制,去優化首次加載頁面白屏時間過長的問題
要點:
1.script標簽用外鏈的src引入文件時,內嵌的js代碼無效。
2.只要不存在defer和async屬性,瀏覽器都會按照script元素在頁面中出現的先后順序對他們依次進行解析(文件下載和代碼執行)。換句話說,在第一個外鏈script下載 -> 執行,由於瀏覽器做了預解析的優化,在第一個js執行的過程中,后面的幾個js會並行下載。第一個script執行完成 -> 第二個外鏈script下載完成 -> 執行,然后第三個,第四個……。這種方式會阻塞頁面的渲染。
3.defer:延遲腳本。腳本會被延遲到整個頁面都解析完畢后再運行。相當於告訴瀏覽器立即下載,但是延遲執行。這種方式不阻塞頁面的渲染。h5規范要求腳本按照出現的順序執行,因此第一個延遲的腳本會優先於第二延遲腳本執行,都會先於DOMContentLoaded事情。在現實中,可能順序不能一定得到保證。ps:用最新谷歌瀏覽器測試過,能保證順序。
4.async:異步腳本。與defer類似,告訴瀏覽器立即下載文件,但是延遲執行,也不阻塞頁面渲染。但是不能保證執行順序。所有,帶有async屬性的script文件之間無法保證順序,不應該有包含互相依賴的js代碼。
補充:
1. 來自阮一峰博客對defer和async異同點說明
defer與async的區別是:defer要等到整個頁面在內存中正常渲染結束(DOM 結構完全生成,以及其他腳本執行完成),才會執行;async一旦下載完,渲染引擎就會中斷渲染,執行這個腳本以后,再繼續渲染。一句話,defer是“渲染完再執行”,async是“下載完就執行”。另外,如果有多個defer腳本,會按照它們在頁面出現的順序加載,而多個async腳本是不能保證加載順序的。
2.外鏈js加載和link外鏈css加載的對比和關系
1.link和外鏈js的下載和執行都是阻塞頁面渲染的。
2.link和外鏈js的下載是並行的。但是不是誰先下載完先執行,執行順序是按上下順利依次執行的。
總結:
一點思考:
1、一般性都要保證js文件的引入順序就是它的執行順序,所以async慎用。
2、script的解析包括:js文件的下載和執行,會阻塞頁面渲染。