23.非同步載入Js的方式有哪些
阿新 • • 發佈:2020-08-10
14. 非同步載入Js的方式有哪些?https://www.cnblogs.com/Lolita-web/p/10456967.html
我們都知道渲染引擎遇到 script 標籤會停下來,等到執行完指令碼,繼續向下渲染,如下:1 |
< script type="text/javascript" src="../../libs/public.js" ></ script >
|
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 >
|