JavaScript異步加載的三種方式——async和defer、動態創建script


一、script標簽的位置

傳統的做法是:所有script元素都放在head元素中,必須等到全部js代碼都被下載、解析、執行完畢后,才能開始呈現網頁的內容(瀏覽器在遇到<body>標簽時才開始呈現內容),這在需要很多js代碼的頁面來說,會造成瀏覽器在呈現頁面時出現明顯的延遲,而延遲期間的瀏覽器窗口將是一片空白。因此。一般把script標簽放在</body>標簽前面。

 

二、嵌入腳本與外部腳本

盡可能使用外部腳本,理由如下:

(1)將所有js文件放在一個文件夾中,再不觸及HTML代碼的情況下編輯js文件,便於維護。

(2)瀏覽器可以根據具體的設置所有外部js文件,同一個文件只需下載一次,可以加快頁面加載的速度。

 

三、async和defer

1、defer="defer"和async="true/false"

html4.0中定義了defer;html5.0中定義了async。

(1)沒有defer或async,瀏覽器會立即加載並執行指定的JS腳本,也就是說,不等待后續載入的文檔元素,讀到JS腳本就加載並執行。

(2)有async,加載后續文檔元素的過程將和JS的加載與執行並行進行(異步)。

(3)有defer,加載后續文檔元素的過程將和JS的加載並行進行(異步),但JS的執行要在所有文檔元素解析完成之后,DOMContentLoaded 事件觸發之前完成。

 

2、defer和async的共同點:

(1)不會阻塞文檔元素的加載。

(2)使用這兩個屬性的腳本中不能調用document.write方法。

(3)允許不定義屬性值,僅僅使用屬性名。

(4)只適用於外部腳本(雖然IE4-IE7還支持對嵌入腳本的defer屬性,但在IE8及之后的版本就只支持外部腳本,對不支持的會直接忽略defer屬性,因此把延遲腳本放在頁面底部仍然是最佳選擇)。

 

3、defer和async的不同點:

(1)每一個async屬性的腳本一旦加載完畢就會立刻執行,一定會在window.onload之前執行,但可能在document的DOMContentLoaded之前或之后執行。不保證按照指定它們的順序來執行,如果JS有依賴性就要注意了。指定異步腳本的目的是不讓頁面等待兩個腳本下載和執行,從而異步加載頁面其他內容,因此,建議異步腳本不要在加載期間修改DOM。

(2)每一個defer屬性的腳本都是在文檔元素完全載入后,一般會按照原本的順序執行,同時一般會在document的DOMContentLoaded之前執行,相當於window.onload,但應用上比 window.onload 更靈活!實際上,defer 更接近於DomContentLoad。事實上,延遲腳本不一定會按順序執行,也不一定會在DOMContentLoaded事件觸發之前執行,因此最好只包含一個延遲腳本。

 

四、動態創建script

在沒有定義defer和async之前,異步加載的方式是動態創建script,通過window.onload方法確保頁面加載完畢再將script標簽插入到DOM中。

  1.  
    function addScriptTag(src){
  2.  
    var script = document.createElement('script');
  3.  
    script.setAttribute("type","text/javascript");
  4.  
    script.src = src;
  5.  
    document.body.appendChild(script);
  6.  
    }
  7.  
    window.onload = function(){
  8.  
    addScriptTag("js/index.js");
  9.  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM