摘要:之前的閉包也好,自執行函數也好,都是模塊化的一些嘗試,直到規范推出之后,模塊化才真正迅猛發展起來。因為有了模塊化的概念,才有了按需加載的概念。
前言
我們來玩樂高積木吧
模塊化Js已經成為了老生常談,不過在JavaScript設計之初,由于定位的問題并沒有提供類的功能,開發者需要模擬出類似的功能,來隔離、組織復雜的JavaScript代碼。之前的閉包也好,自執行函數也好,都是模塊化的一些嘗試,直到CommonJs規范推出之后,模塊化Js才真正迅猛發展起來。
從時間點上來說:
Node遵循CommonJs模塊化規范,NPM包管理系統發展如此迅猛就是CommonJs模塊化規范的最佳實踐
后來在CommonJs的基礎上衍生出了AMD/CMD規范,其各自的實踐分別是RequireJS和SeaJs
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 遵循的是異步加載模塊規范,拿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)先執行.
因為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:
其中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按需加載的概念。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/49922.html
摘要:前言已爛想來大家對自動化構建工具已經不陌生了,自動化構建工具可以幫開發者省去很多重復勞動比如語法糾錯文件打包文件操作,合并壓縮等等常用的自動化構建工具有等等,這些構建工具核心都是依賴第三方插件,通過顆粒化任務,再將這些任務按照合適的方式進行 前言 F5已爛 showImg(https://segmentfault.com/img/bVyS47); 想來大家對自動化構建工具已經不陌生了,...
摘要:前言已爛想來大家對自動化構建工具已經不陌生了,自動化構建工具可以幫開發者省去很多重復勞動比如語法糾錯文件打包文件操作,合并壓縮等等常用的自動化構建工具有等等,這些構建工具核心都是依賴第三方插件,通過顆粒化任務,再將這些任務按照合適的方式進行 前言 F5已爛 showImg(https://segmentfault.com/img/bVyS47); 想來大家對自動化構建工具已經不陌生了,...
摘要:前言已爛想來大家對自動化構建工具已經不陌生了,自動化構建工具可以幫開發者省去很多重復勞動比如語法糾錯文件打包文件操作,合并壓縮等等常用的自動化構建工具有等等,這些構建工具核心都是依賴第三方插件,通過顆粒化任務,再將這些任務按照合適的方式進行 前言 F5已爛 showImg(https://segmentfault.com/img/bVyS47); 想來大家對自動化構建工具已經不陌生了,...
摘要:前言沒有規矩不成方圓用替換來定義變量如果是常量,使用靜態字符串統一用單引號動態拼接成的字符串統一用反引號使用數組成員對變量賦值時,盡量用解構賦值往對象里添加修改屬性時,使用,而不用松散的語法面向對象的寫法一律寫成的形式,摒棄原生的的書寫方法 前言 沒有規矩 不成方圓 用let替換var來定義變量. 如果是常量,使用const 靜態字符串統一用單引號 , 動態拼接成的字符串統一用反...
摘要:前言沒有規矩不成方圓用替換來定義變量如果是常量,使用靜態字符串統一用單引號動態拼接成的字符串統一用反引號使用數組成員對變量賦值時,盡量用解構賦值往對象里添加修改屬性時,使用,而不用松散的語法面向對象的寫法一律寫成的形式,摒棄原生的的書寫方法 前言 沒有規矩 不成方圓 用let替換var來定義變量. 如果是常量,使用const 靜態字符串統一用單引號 , 動態拼接成的字符串統一用反...
閱讀 3469·2023-04-25 21:43
閱讀 3097·2019-08-29 17:04
閱讀 797·2019-08-29 16:32
閱讀 1533·2019-08-29 15:16
閱讀 2144·2019-08-29 14:09
閱讀 2731·2019-08-29 13:07
閱讀 1623·2019-08-26 13:32
閱讀 1320·2019-08-26 12:00