Javascript 如何使用RequireJS实现延迟加载?
我们正在使用主干网、RequireJS和Handlebar构建一个非平凡的web应用程序,我只是好奇。目前,我们的每一款车型都是这样的:Javascript 如何使用RequireJS实现延迟加载?,javascript,backbone.js,requirejs,js-amd,Javascript,Backbone.js,Requirejs,Js Amd,我们正在使用主干网、RequireJS和Handlebar构建一个非平凡的web应用程序,我只是好奇。目前,我们的每一款车型都是这样的: define(['Backbone', 'js/thing/a', 'js/thing/b', 'js/lib/bob'], function(a, b, bob) { return Backbone.Router.extend({ // stuff here }); }); 其中,thing/a、thing/b都有自己的依赖项,例如在把手模
define(['Backbone', 'js/thing/a', 'js/thing/b', 'js/lib/bob'], function(a, b, bob) {
return Backbone.Router.extend({
// stuff here
});
});
其中,thing/a、thing/b都有自己的依赖项,例如在把手模板上,等等。现在发生的是,在my main.js中,所有“顶级”路由器都已加载并初始化;每个顶级路由器都有一组依赖项(模型、视图等),每个依赖项都有自己的依赖项(模板、助手、UTIL等)。基本上是一棵大树
本例中的问题是,整个树在页面加载时被解析和加载。我不介意这样做,因为我们最终将通过优化器运行它,并最终得到一个大文件(将RequireJS简化为基本的模块化框架)。然而,我很好奇你是否可以“按需”加载视图和模板之类的东西
这里解释了“简化的CommonJS包装”,因此我尝试:
define(function(require) {
Backbone = require('Backbone');
return Backbone.Router.extend({
doStuff: function() {
var MyView = require('js/myView');
new MyView().render();
}
});
});
然而,看看Chrome的网络检查器,似乎RequireJS——不知何故,即使没有触发触发doStuff处理程序的路由——仍然加载myView
依赖项。问题:
- 这真的可能吗?在RequireJS中是否有黑色魔法可以在不触发
路由的情况下查找对doStuff
的调用require()
- 这是“按需”延迟加载RequireJS模块和资源的理论正确方法吗
- 如果使用此符号,r.js优化器是否仍像广告中那样工作
- 这真的可能吗?在RequireJS中是否有黑色魔法可以在不触发doStuff路由的情况下寻找对require()的调用?
当您使用“sugar”语法提取对
require
的引用,然后在运行函数之前将它们列为依赖项时。基本上,它成为define的常规样式,第一个参数是dep数组
因此,它不关心require调用在哪里,这就是为什么条件语句被忽略的原因(它还解释了为什么那些require
调用必须使用字符串文字,而不是变量)
这是“按需”延迟加载RequireJS模块和资源的理论正确方法吗?
如您所见,使用sugar语法将不允许条件加载。我脑子里能想到的唯一方法就是使用require
调用和一个dep数组和一个回调:
define(function(require) {
var module1 = require('module1');
// This will only load if the condition is true
if (true) {
require(['module2'], function(module2) {
});
}
return {};
});
mymodule.get().then(function(m) {
// here m is the real mymodule
});
唯一的缺点是另一个嵌套函数,但如果您追求性能,那么这是一个有效的路由
如果使用此符号,r.js优化器是否仍能像广告中那样工作?
如果您使用的是“sugar”语法,那么是的,乐观主义者会很好地工作。例如:
模块/test.js
define(function(require) {
var $ = require('jquery');
var _ = require('underscore');
return {
bla: true
}
});
一旦由r.js编译,这看起来像:
define('modules/test', ['require', 'jquery', 'underscore'], function(require) {
var $ = require('jquery');
var _ = require('underscore');
return {
bla: true
}
});
总之,您可以有条件地加载内容,但正如您所提到的,如果您打算使用r.js优化项目,那么仅使用sugar语法不会带来巨大的开销。您可能还想查看一下 它有一个运行时组件和一个构建时组件。运行时组件允许您将模块延迟为(注意
lazy!
插件):
在前面的上下文中,mymodule
是一个,实际模块将加载get()
,并在then()
回调中可用:
define(function(require) {
var module1 = require('module1');
// This will only load if the condition is true
if (true) {
require(['module2'], function(module2) {
});
}
return {};
});
mymodule.get().then(function(m) {
// here m is the real mymodule
});
要求lazy与r.js集成,以自动创建Javascript文件的“捆绑包”。它还自动处理捆绑包的缓存破坏。这里有几个例子可以让你有一个想法。还有一个问题,那就是整合