2012-10-02 36 views
6

問題1爲什麼我需要加載JavaScript模塊,所有這些加載器之間有什麼區別?

爲什麼我需要在網頁中異步加載我的JavaScript文件?我可以在服務器端看到它的基本原理,但是如果我知道需要在客戶端加載的所有文件,爲什麼我不應該將所有源文件連接到一個文件並在加載頁面時加載?第一個初始頁面加載如此重要,以至於由於檢索每個JS文件的延遲,未來的操作可能會減慢?

問題2

假設答覆問題1,我需要單獨加載JS文件:同步

AMD負載的每一個JS文件asynchrously,CommonJS的負荷。 CJS是服務器端加載所必需的(這就是Node.js的工作原理,如果我沒有弄錯的話)。 AMD似乎更適合客戶。因此,在客戶端使用CJS的唯一原因是與服務器共享代碼。

有沒有辦法讓AMD和CJS很好地發揮作用,這樣客戶端JS文件可以異步加載,但仍然有CJS語法?

(究竟做require.js辦?我不能爲我的生命在他們的網站在字裏行間。)

回答

3

你不「需要」異步或通過一些定製加載加載JavaScript文件。下面是當異步加載或定製的負載可能會帶來益處的一些原因:

  • 在一般情況下不需要的JavaScript文件,你可能想在需要時加載它,而不是所有的時間
  • 當javascript文件是不需要初始頁面顯示,並且您想要最大化您的頁面的第一顯示的速度
  • 當您想要控制加載JavaScript文件時的準確時間
  • 當您決定時,基於某些條件,是否加載JavaScript文件(例如,如果從CDN加載失敗,則爲mi從備份位置向右負載)
  • 當你想腳本加載到與其他事物並行而不是串行化一進入又一個

如果您不需要任何由提供這些利益或其他一些好處程序化加載,那麼你可以使用正常的<script>標籤並讓它們同步加載。

+0

這是真的嗎? –

+0

@JitendraVyas - 是的,這幾乎都是真的。瀏覽器現在具有腳本標記的'defer'和'async'屬性(您可以閱讀[這裏](http://stackoverflow.com/questions/10808109/script-tag-async-defer/10808243#10808243) ),它們可以在不使用加載器的情況下對簡單腳本標記的時間進行一些控制,但上述所有使用加載器的情況仍然存在。 – jfriend00

3

只需連接文件的部分問題不是花費在下載上的時間,而是每個頁面上編譯的時間。

如果你有一個20,000行的文件,並且你只需要其中的600行來啓動和運行所有的東西(假設所有東西都是模塊化的並且是異步的,並且使用任何模式管理資源) ,那麼如果你服務核心程序並根據需要進行擴展(或者延遲計時器,提供大量相互密切相關的功能),那麼你就可以節省自己半秒或更多的時間。

下載的總體時間更長。
使用的HTTP連接總數更高。
但是,讓用戶看到頁面所需的時間更短。
將基本功能添加到頁面所需的時間較短。
然後,可以在加載和初始化之後或按用戶的要求及時輸入額外的功能,並且在這兩種情況下,只要您流入的代碼專注於做那一件事情,並沒有要求其他六個依賴關係,請求和添加功能之間的時間將會很短。

RequireJS基本上使用承諾系統。

它允許您預先聲明依賴關係,並在處理完所有依賴關係後提交要實現的代碼(作爲回調函數)。
如果這些依賴關係具有任何依賴關係,那麼它們將不會被初始化,直到它們的依賴關係被加載爲止。
如果你只是想要它加載和順序並不重要,那麼你不需要給它依賴。

整體道德是,如果你有一個系統,你的所有文件都很小,JS在頁面上的整體重量是非常小的,你只需要幾百行來完成你想要的任何東西第...頁面......你知道你的所有依賴關係在哪裏,你在服務器上有一個系統來確保它們的順序是正確的,等等(再加上你有很棒的文檔,是唯一一個接觸這個代碼的人,而且你每天都在它的內部)...... ......那麼你做什麼都沒有什麼錯。

如果編譯時間超過您所做的HTTP請求的數量,您可能根本沒有看到任何區別。 但是對於長達數十(或數百)萬行的整體應用程序而言,在任何一頁上只需要該功能的一小部分,就可以在頁面加載時間與何時該應用程序對於用戶的基本交互是「準備好」的。

3

如果你想加載你的整個javascript源碼的每一頁,當然,編譯成一個文件。如果您根據用戶採取的操作或基於加載的頁面加載不同的代碼,請使用AMD加載的模塊。另一種方法是列出一堆腳本標記,這些標記當然只能一次加載一次,可能需要一段時間。

AMD不是一個特定的庫,它實際上是一個用於加載你提到的大多數裝載器使用的JavaScript模塊的標準。這意味着它們都使用類似的語法來定義和加載模塊。他們正在考慮讓AMD成爲ECMA腳本規範的一部分。它的用處是你也可以定義依賴關係,所以如果你的代碼需要運行jQuery,你可以把它列爲一個依賴關係,並且它會被加載到你的模塊名字空間中。

define([ 'jquery' ], function ($) { 
    // use jquery in here without clouding up the global namespace 

    return {}; // return your module for use in a different module or whatever 
}; 

在這個例子中,所定義的模塊中的代碼將不被運行,直到jquery的模塊被下載。然後它會將jquery模塊直接注入到新定義的模塊中,作爲參數$

您現在可以將代碼整齊地組織到包含模塊的文件中。您的模塊都不會使全局命名空間雲端化。所有的依賴關係都將在你的模塊運行之前一定會被加載(對於相關的代碼,沒有加載競爭條件的bug)。

另一個優點是您可以將您的加載器設置爲對同一模塊使用不同的路徑,因此您可以將jquery模塊的路徑定義爲'https://ajax.googleapis.com/ajax/libs/jquery /1.8.2/jquery.min.js'放在你的代碼中,儘管它幾乎可以在每個模塊中使用。現在,當我需要將我的jquery版本更新到1.8.3時,我可以簡單地在我的代碼中更改一個點的路徑,並將它用於每個使用jquery作爲依賴項的模塊。當您使用模塊存根進行測試或某些模塊的調試版本時,這對於輕鬆切換也很有用。

現在,這不是小型項目所必需的。然而,您的項目越大,這種類型的加載開始越有意義。

相關問題