異步加載js
javascript 異步加載的三種方案
- defer 異步加載,但要等到dom文檔全部解析完纔會被執行。能把js寫在script 標籤裏。只有IE能用。
- async 異步加載,加載完就執行,async只能加載外部腳本,不能把js寫在script 標籤裏。除了IE都能用。
以上兩種方式執行時不阻塞頁面
<script type="text/javascript" src="tool1.js" defer></script>
<script type="text/javascript" src="tool2.js" async></script>
- 創建script,插入到DOM中,加載完畢後callBack。
方法一:示例引用的外部js文件爲tool.js,數據格式爲JSON格式
<script>
//函數調用
loadScript('tool.js','text');
//函數定義
function loadScript(url,callback){
var script = document.createElement('script');
script.type = "text/javascript";
if(script.readyState){//IE
//loading interactive loaded complete 狀態發生改變就會執行的函數 僅IE
script.onreadystatechange = function(){
if(script.readyState == "complete" || script.readState == "loaded"){
tools[callback]();
}
}
}else{
script.onload = function(){
//Safari chrome firefox opera
//tool.js 的方法調用
tools[callback]();
}
}
script.src = url;
document.head.appendChild(script);
}
</script>
方法二:示例引用的外部js文件爲tool.js。
<script>
//domTree + cssTree = randerTree
//redlow重排效率低 dom節點的刪除,添加 dom節點的寬高變化,display none--> block offsetWidth offsetLeft
//repaint重繪影響較小 對CSS樣式做的變化
//函數調用
loadScript('tool.js',function(){
text();
});
//函數定義
function loadScript(url,callback){
var script = document.createElement('script');
script.type = "text/javascript";
if(script.readyState){
//loading interactive loaded complete 狀態發生改變就會執行的函數 僅IE
script.onreadystatechange = function(){
if(script.readyState == "complete" || script.readState == "loaded"){
callback();
}
}
}else{
script.onload = function(){
//Safari chrome firefox opera
//tool.js 的方法調用
callback();
}
}
script.src = url;
document.head.appendChild(script);
}
</script>
js時間線
1、創建Document對象,開始解析web頁面。解析HTML元素和他們的文本內容後添加Element對象和Text節點到文檔中。這個階段document.readyState = ‘loading’。
2、遇到link外部css,創建線程加載,並繼續解析文檔。
3、遇到script外部js,並且沒有設置async、defer,瀏覽器加載,並阻塞,等待js加載完成並執行該腳本,然後繼續解析文檔。
4、遇到script外部js,並且設置有async、defer,瀏覽器創建線程加載,並繼續解析文檔。
對於async屬性的腳本,腳本加載完成後立即執行。(異步禁止使用document.write())
5、遇到img等,先正常解析dom結構,然後瀏覽器異步加載src,並繼續解析文檔。
6、當文檔解析完成,document.readyState = ‘interactive’。
7、文檔解析完成後,所有設置有defer的腳本會按照順序執行。(注意與async的不同,但同樣禁止使用document.write());
8、document對象觸發DOMContentLoaded事件,這也標誌着程序執行從同步腳本執行階段,轉化爲事件驅動階段。
9、當所有async的腳本加載完成並執行後、img等加載完成後,document.readyState = ‘complete’,window對象觸發load事件。
10、從此,以異步響應方式處理用戶輸入、網絡事件等。
本篇博客啓發自嗶哩嗶哩/2020權威「JavaScript/JS」零基礎入門精英課/。視頻裏的老師講的很棒,推薦給大家json,異步加載,時間線