23.異步加載Js的方式有哪些


14. 異步加載Js的方式有哪些?https://www.cnblogs.com/Lolita-web/p/10456967.html

 
我們都知道渲染引擎遇到 script 標簽會停下來,等到執行完腳本,繼續向下渲染,如下:
1
< script  type="text/javascript" src="../../libs/public.js" ></ script >

 

這樣會阻止瀏覽器的后續解析,只有當前加載完成才能進行下一步操作,所以默認同步執行才是安全的。但是這樣如果JS中有輸出document內容、修改dom、重定向的行為,就會造成頁面阻塞。所以一般建議把<script>標簽放在<body>結尾處,這樣盡可能減少頁面阻塞。
異步加載又被稱為非阻塞加載,瀏覽器在下載JS的同時,還會進行后續頁面處理。那么如何實現js異步加載呢?下面整理了多種實現方案供大家參考:
 
方法一:Script Dom Element
1
2
3
4
5
6
7
8
(function(){
     var scriptEle = document.createElement("script");
     scriptEle.type = "text/javasctipt";
     scriptEle.async = true;
     scriptEle.src = "http://cdn.bootcss.com/jquery/3.0.0-beta1/jquery.min.js";
     var x = document.getElementsByTagName("head")[0];
     x.insertBefore(scriptEle, x.firstChild);       
  })();

  

<async>屬性是HTML5中新增的異步支持。此方法被稱為Script DOM Element方法
1
2
3
4
5
6
7
8
(function(){;
     var ga = document.createElement('script');
     ga.type = 'text/javascript';
     ga.async = true;
     ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
     var s = document.getElementsByTagName('script')[0];
     s.parentNode.insertBefore(ga, s);
})();

  

但是這種加載方式執行完之前會阻止onload事件的觸發,而現在很多頁面的代碼都在onload時還執行額外的渲染工作,所以還是會阻塞部分頁面的初始化處理。
 
方法二:onload時的異步加載
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
(function(){
     if(window.attachEvent){
         window.attachEvent("load", asyncLoad);
     }else{
         window.addEventListener("load", asyncLoad);
     }
     var asyncLoad = function(){
         var ga = document.createElement('script');
          ga.type = 'text/javascript';
         ga.async = true;
         ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
         var s = document.getElementsByTagName('script')[0];
         s.parentNode.insertBefore(ga, s);
     }
})();

  

這種方法只是把插入script的方法放在一個函數里面,然后放在window的onload方法里面執行,這樣就解決了阻塞onload事件觸發的問題。
注:DOMContentLoaded與load的區別。前者是在document已經解析完成,頁面中的dom元素可用,但是頁面中的圖片,視頻,音頻等資源未加載完,作用同jQuery中的ready事件;后者的區別在於頁面所有資源全部加載完畢。
 
方法三:$(document).ready()
需要引入jquery,兼容所有瀏覽器  
1
2
3
$(document).ready(function() {
      alert("加載完成!");
  });

  

 
方法四:<script>標簽的async="async"屬性
  • async屬性是HTML5新增屬性,需要Chrome、FireFox、IE9+瀏覽器支持
  • async屬性規定一旦腳本可用,則會異步執行
  • async屬性僅適用於外部腳本
  • 此方法不能保證腳本按順序執行
  • 他們將在onload事件之前完成
1
< script  type="text/javascript" src="xxx.js" async="async"></ script >

  

方法五:<script>標簽的defer="defer"屬性
  • defer屬性規定是否對腳本執行進行延遲,直到頁面加載為止
  • 如果腳本不會改變文檔的內容,可將defer屬性加入到<script>標簽中,以便加快處理文檔的速度
  • 兼容所有瀏覽器
  • 此方法可以確保所有設置了defer屬性的腳本按順序執行
1
< script  type="text/javascript" defer></ script >

  

方法六:es6模塊type="module"屬性
瀏覽器對於帶有type=”module”的<script>,都是異步加載,不會造成堵塞瀏覽器,即等到整個頁面渲染完,再執行模塊腳本,等同於打開了<script>標簽的defer屬性 。如下:
 
1
< script  type="module" src="XXX.js"></ script >

  

ES6模塊允許內嵌在網頁中,語法行為與加載外部腳本一致,如下:
1
2
3
4
< script  type="module">
    import utils from "./utils.js";
    // other code
</ script >


免責聲明!

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



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