JavaScript基礎-----js時間線&異步加載

1. JavaScript加載時間線(理論):

    js本是單線程執行,瀏覽器爲幾個明顯的耗時任務單獨開闢線程解決耗時問題(也就是 異步

    時間線:瀏覽器在運行一個頁面時,首先會初始化js的功能,當初始化初試完js這一個功能後,也就是js開始發揮作用那一刻,開始記載着這一系列瀏覽器要發生的過程;

    這一系列順序分爲十個步驟:

    (1).創建 Document 對象,開始解析Web頁面;此階段狀態document.readyState = 'loading'

    (2).遇到 link 外部 css 文件,創建線程加載,並繼續解析文檔(異步);

    (3).遇到 script 外部 js 文件,並且沒有設置async、defer 的時候,瀏覽器加載並阻塞,等待 js 加載完成並執行改腳本,繼續解析文檔(異步時最好別用document.write(),容易出問題);

    (4).遇到 script 外部 js 文件,並且有設置async、defer的時候,瀏覽器創建線程加載,並繼續解析文檔(異步);

    (5).遇到 img 等,瀏覽器創建線程加載,並繼續解析文檔;

    (6).當文檔解析完成,也就是DOM Tree加載完成時,此階段狀態document.readyState = 'interactive'

    (7).接着,所有設置有 defer 的腳本會按照順序執行;

    (8).document 對象觸發DOMContentLoaded事件,這也標誌着程序執行從同步腳步執行階段,轉化爲事件驅動階段

    (9).當所有async的腳本加載完成並執行後,img等加載完成後,此階段狀態爲document.readyStste = 'complete'window對象觸發load事件;

    (10).從此,以異步響應方式處理用戶輸入,網絡事件等

2.異步的加載:

    (1).同步模式,又稱阻塞模式,會阻止瀏覽器的後續處理,停止後續的解析,只有噹噹前加載完成,才能進行下一步操作。所以默認同步執行纔是安全的。但這樣如果js中有輸出document內容、修改dom、重定向等行爲,就會造成頁面堵塞。所以一般建議把<script>標籤放在<body>結尾處,這樣儘可能減少頁面阻塞

    (2).異步加載又叫非阻塞加載,瀏覽器在下載執行js的同時,還會繼續進行後續頁面的處理,不會造成頁面阻塞;

    (3).異步加載的方式一:創建動態的script標籤

//第一種
(function(){
    var att = document.createElement("script");     //創建script標籤
    att.type = "text/javasctipt";    //添加類型
    att.async = true;      //true爲異步支持
    att.src = "http://cdn.bootcss.com/jquery/3.0.0-beta1/jquery.min.js";     //添加要放入的js文件
//第一種添加位置
    var x = document.getElementsByTagName("head")[0];
    x.insertBefore(att, x.firstChild);		//將這個script標籤添加到head下面
//第二種添加位置
    var s = document.getElementsByTagName('script')[0]; 
    s.parentNode.insertBefore(att, s);    //將這個script標籤添加到第一個script標籤的之前
//第三種添加位置
    document.head.appendChild(att)     //添加到head下title標籤下面
 })();

            創建script標籤,插入到dom中,加載完畢執行回調函數

//第二種
function loadScript(url, callback){
    var script = document.createElement('script');
    script.type = "text/javascript";
//處理兼容性
    if(script.readyState){           //IE9以下
        script.onreadystatechange = function(){
            if(script.readyState=='complete'||script.readyState=='loaded'){
                callback();//obj[(callback)]()
            }
        }
    }else{
        script.onload = function () {          //firefox chrome safair opera
            callback();//obj[(callback)]()
        }
    }
    script.src = url;   //js文件路徑
    document.head.appendChild(script);
}
loadScript(url,callback)

    但是這種加載方式執行完之前會阻止onload事件的觸發,而現在很多頁面的代碼都在onload時還執行額外的渲染工作,所以還是會阻塞部分頁面的初始化處理。

    (4).異步加載的方式二:defer 異步加載 :  

<script type="text/javascript" src="example.js" defer="defer"></script> 

        defer 異步加載,但要等到dom文檔全部解析完才能被執行。只有IE能用,可以把代碼寫在script標籤裏  

    (5).異步加載的方式三:async 異步加載:

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

        async異步加載,加載完就執行,async只能加載外部腳本,不能把js代碼寫在script標籤裏

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章