切圖崽的自我修養-使用模塊化JS

前言

咱們來玩樂高積木吧html

模塊化Js已經成爲了老生常談,不過在JavaScript設計之初,因爲定位的問題並無提供類的功能,開發者須要模擬出相似的功能,來隔離、組織複雜的JavaScript代碼。以前的閉包也好,自執行函數也好,都是模塊化的一些嘗試,直到CommonJs規範推出以後,模塊化Js才真正迅猛發展起來。node

從時間點上來講:瀏覽器

  1. Node遵循CommonJs模塊化規範,NPM包管理系統發展如此迅猛就是CommonJs模塊化規範的最佳實踐緩存

  2. 後來在CommonJs的基礎上衍生出了AMD/CMD規範,其各自的實踐分別是RequireJSSeaJs服務器


CommonJs同步加載規範

CommonJs規範遵循的是同步加載模塊規範,即:網絡

var A = require(./module/a);
A.funA();
var B = require(./module/b);
B.funB();

即只有a.js加載完之後,才能接着向下執行A.funA();才能接着向下加載b.js, 等b.js加載完以後,才能向下執行B.funB();。但這種同步串行的加載方式確對效率並無多大影響,由於CommonJs是在Node上運行,處於服務器環境,服務器環境對模塊的加載等同於硬盤的讀寫速度,是很是很是快的。閉包


AMD/CMD異步加載規範

AMD/CMD 遵循的是異步加載模塊規範,拿CMD規範的SeaJs舉例:異步

define(function(require,exports,module){
    require.async('./module/a', function(){alert(1)}
    require.async('./module/b', function(){alert(2)}
  });

其中,alert(1) 和alert(2)的執行順序是不固定的,由於是採用異步加載模塊的方式,a模塊和b模塊是並行加載的 ,誰先加載完畢,誰先掉用回調. 由於網絡和文件大小的緣由, 固然有多是b模塊先加載完畢,因此多是alert(2)先執行.async

由於requireJs(AMD)SeaJs(CMD) 都是運行在客戶端瀏覽器上的. 模塊的加載速度和網絡情況有關係,加載狀況是很是不穩定,若是採用同步串行加載的方式,會出現由於前面的模塊加載耗時太長而阻塞了它以後的模塊的加載. 因此AMD/CMD纔有了異步的解決方案模塊化

(固然,AMD/CMD也支持同步加載)


按需加載

按需加載是模塊化Js引申出來的概念.咱們可讓特定的頁面加載特定的JS,就像搭積木恰好把房子搭起來同樣,用Js模塊組合的方式能夠項目搭建起來,保證不缺乏任何一個必要的模塊,也保證不會有任何一個多餘的模塊.

若是index.html只須要彈窗功能和滑動功能,就只加載pop.js和slip.js

提及來卻是挺簡單,但實際上呢?

實際上也很是簡單,拿seaJS舉例來講,頁面index.html引用了Sea.js後,就能夠以index.js爲加載入口,對頁面所需的七七八八的JS模塊進行加載:

index.html:

<script src="static/js/lib/sea.js" id="seaJSnode"></script>
<script>
    seaJS.use("./index.js");      
</script>

其中index.js:

define(function(require,exports,module){
     //引入模塊a
     var A = require('./module/a'); 
     //引入模塊b
     var B = require('./module/b')     
     
     ...
});

其中a.js又依賴了其餘的模塊:

define(function(require,exports,module){
     //引入模塊c
     var C = require('./module/c');          
     ...
});

無論這個依賴關係有多複雜,層級有多深,seaJS的模塊加載器會遞歸找到全部頁面index.html依賴的Js,就拿例子來講,和index.html有關的依賴有 入口文件index.js和它依賴的a.js, b.js ,而且還有a.js依賴的 c.js 因此最後index.html實際上會加載index.js, a.js, b.js , c.js

這樣就實現了頁面須要什麼模塊,就加載什麼模塊(和這些模塊依賴的模塊),從而實現了按需加載。

但有同窗估計又想到了,這個地方有個小缺陷,雖然模塊化Js使得加載邏輯更清晰了,可是如此碎片化的Js會增長頁面http的請求數,從而影響頁面的加載速度。

沒錯,因此咱們一般在上線前會利用自動化工具對當前頁面依賴的全部Js作一個合併處理,即合併壓縮成一個Js文件, 這樣能最大程度上的利用瀏覽器緩存,減小Http請求數。

(注:Js模塊書寫的時候請儘可能避免循環引用的問題,即a.js引用了c.js,反過來c.js又引用了a.js. 這確定是模塊書寫不規範形成的,請檢查這兩個模塊的邏輯是否有重疊. 固然,除此以外循環引用仍是有別的辦法解決的,這裏就不提了)


結語

總而言之,模塊化Js目前有兩大規範(固然要說成三種規範也能夠,不過在做者本人看來AMD/CMD並無本質上的區別)

  • CommonJS同步加載模塊規範,運行在服務端

  • AMD/CMD 異步加載模塊規範,運行在客戶端

由於CommonJs規範在服務器端的同步串行加載Js模塊的方式並不適用於客戶端瀏覽器,因此纔有了AMD/CMD規範延伸出異步並行加載Js模塊的方式。

由於有了Js模塊化的概念,纔有了Js按需加載的概念。

相關文章
相關標籤/搜索