AMD 和 CMD

腳本的無阻塞加載

moduleA.js 代碼

console.log("I'm A");
/*
此處可以放jquery源碼
使得該文件變大,以便異步加載時看效果
*/

moduleB.js 代碼

console.log("I'm B");

同步加載

<body>
    <script src="moduleA.js" onload="console.log('A loaded')"></script>
    <script src="moduleB.js" onload="console.log('B loaded')"></script>
</body>

輸出

I'm A
A loaded
I'm B
A loaded

defer 和 async

defer:在文檔完成解析後,觸發 DOMContentLoaded 事件前執行。如果缺少 src 屬性(即內嵌腳本),該屬性不應被使用,因爲這種情況下它不起作用。對動態嵌入的腳本使用 async=false 來達到類似的效果。

async:是否在允許的情況下異步執行該腳本。該屬性對於內聯腳本無作用 (即沒有src屬性的腳本)。

defer 示例

<body>
    <script defer src="moduleA.js" onload="console.log('A loaded')"></script>
    <script src="moduleB.js" onload="console.log('B loaded')"></script>
</body>

輸出

I'm B
B loaded
I'm A
A loaded

async 示例

異步加載

<body>
    <script>
        loadScript("moduleA.js", "async A loaded");
        loadScript("moduleB.js", "async B loaded");

        function loadScript(url, text) {
            var srcEle = document.createElement("script");
            srcEle.src = url;
            srcEle.async = true;
            srcEle.onload = function () {
                console.log(text);
            };
            document.body.appendChild(srcEle);
        }
    </script>
</body>
動態創建的script標籤,async默認爲true;

輸出

I'm B
async B loaded
I'm A
async A loaded

相同之處:

  • 加載文件時不阻塞頁面渲染
  • 使用這兩個屬性的腳本中不能調用document.write方法
  • 有腳本的onload的事件回調

不同之處

  • 每一個async屬性的腳本都在它下載結束之後立刻執行,同時會在window的load事件之前執行。所以就有可能出現腳本執行順序被打亂的情況;
  • 每一個defer屬性的腳本都是在頁面解析完畢之後,按照原本的順序執行,同時會在document的DOMContentLoaded之前執行

AMD和CMD

AMD

RequireJS的標準

特點:依賴前置、預執行

define(['./a', './b'], function(a, b) {
    //運行至此,a.js和b.js已經下載完成
    //a模塊和b模塊已經執行完
    a.doing();
    b.doing();
});

CMD

SeaJS的標準

特點:依賴就近、懶執行

define(function(require, exports, module) {
    var a = require("./a");
    //等待a.js下載、執行完
    a.doing();
    var b = require("./b");
    //等待b.js下載、執行完
    b.doing();
});

reference

AMD 和 CMD 的區別有哪些?

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