我有一个带有多个模块的应用程序,需要在加载完成后立即呈现。这个想法是每个模块执行其专用的渲染功能,而不管其他模块是什么?的状态。
这里是主要模块的实现:
;(function(doc, win, undefined) {
'use strict';
define(['module', 'domReady!'], function(main) {
var modules = main.config().modules;
while (modules.length) {
require([].concat(modules.shift()), function(module) {
module.init();
});
}
});
}(document, window));
似乎尽管每个模块在加载后都应该立即渲染,但在所有模块完成加载之前屏幕上不会出现任何内容。这会导致进入应用程序时出现延迟,并且不会显示应用程序已开始执行。什么可能导致这种行为以及如何尽可能顺利地初始化应用程序?
答案 0 :(得分:1)
提供您正在寻找的效果不是AMD语义的一部分。您唯一的保证是,传递给require
的回调不会运行,直到依赖于回调的依赖关系数组中列出的模块及其依赖项被加载。
RequireJS无法很好地控制浏览器如何将请求发送到服务器。例如,如果发生这种情况,那么当您发出请求时,浏览器已经有太多其他待处理请求(对于样式表,图像或其他必须加载的内容,除了您通过require
要求的模块之外),浏览器可能决定延迟RequireJS'直到先前的请求得到解决。
如何在服务器端解析请求也会影响将以什么顺序发生的事情。
然后是您的应用程序的结构。假设main.config().modules
包含['A', 'B', 'C']
。因此,您希望按顺序加载A
,B
,C
并让它们尽快初始化。然而,事实证明所有这些模块也依赖于jquery
。当RequireJS执行A
时,它会运行define(['jquery], function ($) {...
。好的,现在必须提取jquery
。在提取jquery
时,B
和C
也可能会等待它。因此,RequireJS将执行A
,B
,C
以及以接近连续的顺序等待它们的回调。只有一个依赖项,它可能不是什么大问题,但如果你的模块依赖于大量其他常见模块,它会加起来,最终结果是你会在加载公共模块时看到明显的等待,然后看起来像{ {1}},A
,B
批量执行。
可以使用RequireJS'自己的优化器或另一个理解AMD模块的优化器,试图将您的模块组合成有利于您正在寻找的结果的包。进行这种优化需要开发人员仔细分析应用程序的结构。在一般情况下,没有单一标志,选项或插件可以打开以获得您所追求的结果。此外,如上所述,浏览器和服务器的工作方式可能会破坏它。
有一点我应该提到完整性。您可以强制执行顺序初始化,但仅在上一个模块加载后请求一个模块:
C
但是,这里的成本是;(function(doc, win, undefined) {
'use strict';
define(['module', 'domReady!'], function(main) {
var modules = main.config().modules;
function next() {
var name = modules.shift();
if (name === undefined) {
return;
}
require([name], function (module) {
// When one module has loaded, we initiate the request for the
// next one.
next();
// And init what we've got now.
module.init();
});
}
next();
});
}(document, window));
仅在B
加载后请求等。而在原始代码中,所有模块都是直接请求的。这可能导致总的初始化时间更长。