1. 程式人生 > >JS非同步載入的幾種方式

JS非同步載入的幾種方式

1、同步載入

我們平常寫JS的時候都是用的阻塞模式如

<script type="text/javascript" src="../../libs/crypto/abc.js" ></script>
<script type="text/javascript" src="../../libs/crypto/abcd.js" ></script>

這種模式會阻止瀏覽器的後續解析,只有當前載入完成才能進行下一步操作,所以默認同步執行才是安全的。

但是這樣如果JS中有輸出document內容、修改dom、重定向的行為,就會造成頁面阻塞。

建議把<script>標籤放在<body>結尾處,這樣儘可能減少頁面阻塞。

2、非同步載入

非同步載入又被稱為非阻塞載入,瀏覽器在下載JS的同時,還會進行後續頁面處理。

有如下五種方式

方法一:Script Dom Element

(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方法

(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時的非同步載入

(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

  • 相容所有瀏覽器

$(document).ready(function() {
        alert("載入完成!");
      });

方法四:<script>標籤的async="async"屬性

  • async屬性是HTML5新增屬性,需要Chrome、FireFox、IE9+瀏覽器支援

  • async屬性規定一旦指令碼可用,則會非同步執行

  • async屬性僅適用於外部指令碼

  • 此方法不能保證指令碼按順序執行

  • 他們將在onload事件之前完成

<script type="text/javascript" src="xxx.js" async="async"></script>

方法五:<script>標籤的defer="defer"屬性

  • defer屬性規定是否對指令碼執行進行延遲,直到頁面載入為止

  • 如果指令碼不會改變文件的內容,可將defer屬性加入到<script>標籤中,以便加快處理文件的速度

  • 相容所有瀏覽器

  • 此方法可以確保所有設定了defer屬性的指令碼按順序執行

<script type="text/javascript" defer></script>