AMD 和 CMD

腳本的無阻塞加載

moduleA.js 代碼html

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

moduleB.js 代碼jquery

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

同步加載app

<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

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

defer 示例

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

輸出url

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

async 示例

異步加載code

<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;

輸出htm

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 的區別有哪些?

相關文章
相關標籤/搜索