首頁 >web前端 >js教程 >對於Javascript載入的解析

對於Javascript載入的解析

不言
不言原創
2018-07-11 10:36:511277瀏覽

這篇文章主要介紹了關於Javascript載入的解析,有著一定的參考價值,現在分享給大家,有需要的朋友可以參考一下

1. 瀏覽器載入

    (1) 同步載入

        在網頁中,瀏覽器載入js檔案的方式是透過3f1c4e4b6b16bbbd69b2ee476dc4f83a標籤。如下所示:

//内嵌脚本
<script type="text/javacript">    
// code here!
</script>
//加载外部脚本
<script type="text/javascript src="path/demo.js"></script>

3f1c4e4b6b16bbbd69b2ee476dc4f83a標籤很方便,只要加入後,瀏覽器便可讀取並運行,但是在讀取的時候,瀏覽器是按照3f1c4e4b6b16bbbd69b2ee476dc4f83a標籤的出現順序,讀取Javascript文件,然後立即運行,導致在多個文件相互依賴的情況下,依賴性最小的文件必須放在最前面,依賴性最大的必須放在最後面,否則代碼會報錯,這一點,想必大家在使用bootstrap的時候都深有體會。另一方面,瀏覽器採用同步模式載入3f1c4e4b6b16bbbd69b2ee476dc4f83a標籤,也就是說,頁面會等待JavaScript檔案載入完成,然後再執行後面的程式碼。當存在很多3f1c4e4b6b16bbbd69b2ee476dc4f83a標籤時,瀏覽器無法同時讀取,必須讀完一個再讀取另一個,造成讀取時間大大延長,頁面回應緩慢,影響使用者體驗。同步模式又稱為阻塞模式,會阻止瀏覽器的後續處理,停止後續的解析,只有目前載入完成,才能進行下一步操作,所以預設同步執行才是安全的。但這樣如果js中有輸出document內容、修改DOM、重定向等行為,就會造成阻塞。所以一般建議把3f1c4e4b6b16bbbd69b2ee476dc4f83a標籤放在6c04bd5ca3fcae76e30b72ad730ca86d結尾處,這樣能減少頁面阻斷。

    (2)非同步載入

        為了解決這個問題,ES5中採用了DOM方法,動態載入JavaScript腳本檔案

function loadScript(url) {    
var script = document.createElement("script");
    script.type="text/javascript";
    script.src=url;
    document.body.appendChild(script);
}

        這種方式透過建立一個新的3f1c4e4b6b16bbbd69b2ee476dc4f83a標籤,並設定其src屬性,非同步讀取javacript檔案

這樣不會造成頁面阻塞,但會有另一個問題,如果其他腳本檔案依賴它,此時無法保證此腳本何時能夠載入完畢。

        另一種載入方式是利用defer和async屬性,讓腳本非同步載入。渲染引擎遇到這一行命令,就會開始下載外部腳本,但不會等它下載和執行,而是直接執行後面的命令。 defer和async的區別是: defer要等到整個頁面在內存中正常渲染結束(DOM結構完全生成,以及其他腳本執行完成),才會執行;async一旦下載完成,渲染引擎就會中斷渲染,執行這個腳本以後,再繼續渲染。即defer是渲染完再執行,async是下載完就執行。另外,如果有多個defer腳本,會按照它們在頁面中出現的順序加載,而多個async腳本是不能保證加載順序的。

        IE9及以下版本在延遲實作上有一些相當糟糕的錯誤,導致執行順序無法保證。 如果你需要支援30dbd0fdc117237fc4864ac190eb98952cacc6d41bbb37262a98f745aa00fbf0 27893951ee31aa4ab68c289425ee4a992cacc6d41bbb37262a98f745aa00fbf0

        如何選用defer和async。如果使用的script是個模組,且不依賴任何其它script檔案時使用async;如果腳本依賴其它script或則被其它script依賴,就使用defer;倘若腳本檔案很小且被一個async script依賴,就使用內嵌script把該檔案放在所有async script前面。

        另外一種方法是onload事件的非同步載入。

(function(){
    if(window.attachEvent) {
        window.attachEvent("load", asyncLoad);
    } else if(window.addEventListener) {
        window.addEventListener("load", asyncLoad);
    } else {        window.onload = asyncLoad;    }  
    var asyncLoad = function() {
        var script = document.createElement("script");
        script.type="text/javascript";
        script.async = true;
        script.src = (&#39;https:&#39;==document.location.protocol ? &#39;https://ssl&#39; :  &#39;http:www&#39;) + &#39;.baidu.com/demo.js&#39;;
        var s = document.getElementsByTagName(&#39;script&#39;)[0];
        s.parentNode.insertBefore(script, s);
    };
)();

        這個方法是將插入script的方法放在一個函數裡面,然後放在window的onload方法裡面執行,這樣就解決了阻塞onload事件的觸發問題。

        由於Javascript的動態性,還有很多非同步載入方法:XHR Injection、XHR eval、Script In Iframe、document.write("