前言:
向HTML頁面中插入JavaScrip的主要方法,就是使用<script>标簽。主要探讨<script>标簽的在HTML頁面的渲染機制。對應的業務場景:從js的加載機制,去優化首次加載頁面白屏時間過長的問題
要點:
1.script标簽用外鍊的src引入檔案時,内嵌的js代碼無效。
2.隻要不存在defer和async屬性,浏覽器都會按照script元素在頁面中出現的先後順序對他們依次進行解析(檔案下載下傳和代碼執行)。換句話說,在第一個script元素包含的代碼解析完成後,第二個script包含的代碼才會被解析,然後第三個,第四個……。這種方式會阻塞頁面的渲染。
3.defer:延遲腳本。腳本會被延遲到整個頁面都解析完畢後再運作。相當于告訴浏覽器立即下載下傳,但是延遲執行。這種方式不阻塞頁面的渲染。h5規範要求腳本按照出現的順序執行,是以第一個延遲的腳本會優先于第二延遲腳本執行,都會先于DOMContentLoaded事情。在現實中,可能順序不能一定得到保證。ps:用最新谷歌浏覽器測試過,能保證順序。
4.async:異步腳本。與defer類似,告訴浏覽器立即下載下傳檔案,但是延遲執行,也不阻塞頁面渲染。但是不能保證執行順序。所有,帶有async屬性的script檔案之間無法保證順序,不應該有包含互相依賴的js代碼。
補充:來自阮一峰部落格對defer和async異同點說明
defer與async的差別是:defer要等到整個頁面在記憶體中正常渲染結束(DOM 結構完全生成,以及其他腳本執行完成),才會執行;async一旦下載下傳完,渲染引擎就會中斷渲染,執行這個腳本以後,再繼續渲染。一句話,defer是“渲染完再執行”,async是“下載下傳完就執行”。另外,如果有多個defer腳本,會按照它們在頁面出現的順序加載,而多個async腳本是不能保證加載順序的。
總結:
一點思考:
1、一般性都要保證js檔案的引入順序就是它的執行順序,是以async慎用。
2、script的解析包括:js檔案的下載下傳和執行。下載下傳可不阻塞頁面渲染,執行一定會阻塞頁面渲染(有待考究)。
3、假如defer在現代浏覽器(特别是移動端),都能遵循h5規範按順序執行。那麼是否可以在每個script标簽加上defer屬性,優點如下:1.js檔案解析不阻塞HTML頁面的渲染。2.js檔案解析可分為兩步,第一步下載下傳js檔案,相較不加defer屬性的多個script标簽而言,加了defer可實作異步并行下載下傳script檔案(有待考究);第二部解析js檔案,按順序同步執行js代碼。以此達到最快的js解析速度(下載下傳js檔案效率提高)。
以上總結是一些思考,有些地方有待demo測試驗證。