这里问题的答案是“视情况而定”。我说的是在大型应用程序中使用过 RequireJS 但没有彻底阅读过 RequireJS 代码的人。(只是指出,从里到外了解 RequireJS 内幕的人可能会做出与我不同的解释。)成本require
可以分解为 3 种成本场景:
如果模块从未被加载,require
则从服务器加载文件,执行文件,执行模块的工厂函数并返回对模块的引用。(从网络加载文件的成本通常使其他成本相形见绌。)
如果模块已经加载但从不需要,require
则执行模块的工厂函数并返回对该模块的引用。(这通常发生在优化的应用程序中。)
如果模块已经被加载并且需要,require
则返回对该模块的引用。
成本方案 1 > 成本方案 2 > 成本方案 3。
首先,让我们考虑每个文件有一个模块的情况。应用程序未优化。我有一个名为的模块module1
,在蓝月亮中需要一次。它在主应用程序中的使用可以这样建模:
define(["module1", <bunch of other required modules>],
function (module1, <bunch of other modules variables>) {
[...]
if (rare_condition_happening_once_in_a_blue_moon)
module1.use();
[...]
});
在这里,即使我不使用模块,我也总是为成本场景 1 付出代价。最好这样做:
define([<bunch of required modules>],
function (<bunch of module variables>) {
[...]
if (rare_condition_happening_once_in_a_blue_moon)
require(["module1"], function (module1) {
module1.use();
});
[...]
});
这样一来,我就可以为加载模块付出一次代价。
现在,如果我需要module
重复使用怎么办?这可以建模为:
define(["module1", <bunch of other required modules>],
function (module1, <bunch of other modules variables>) {
[...]
for(iterate a gazillion times)
module1.use();
[...]
});
在这种情况下,成本方案 1 支付一次,仅此而已。如果我require
这样使用:
define([<bunch of required modules>],
function (<bunch of module variables>) {
[...]
for(iterate a gazillion times)
require(["module1"], function (module1) {
module1.use();
});
[...]
});
我支付了 1 号成本方案一次和3次(无数次 - 1)成本方案号 3。归根结底,是否module1
应将其包含在呼叫的要求中define
或单独的require
呼叫中取决于具体情况你的申请。
如果应用程序已通过使用r.js
或自制优化进行了优化,则分析会发生变化。如果应用程序经过优化,所有模块都在一个文件中,则每次在上述情况下支付成本方案 1 时,您将改为支付成本方案 2。
为了完整起见,我将补充一点,如果您不提前知道您可能要加载的模块,则使用require
是必要的。
define([<bunch of other required modules>],
function (<bunch of other modules variables>) {
[...]
require(<requirements unknown ahead of time>, function(m1, m2, ...) {
m1.foo();
m2.foo();
[...]
});
[...]
});