完成加载后单独渲染每个模块

时间:2017-02-06 14:57:43

标签: javascript requirejs amd

我有一个带有多个模块的应用程序,需要在加载完成后立即呈现。这个想法是每个模块执行其专用的渲染功能,而不管其他模块是什么?的状态。

这里是主要模块的实现:

;(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));

似乎尽管每个模块在加载后都应该立即渲染,但在所有模块完成加载之前屏幕上不会出现任何内容。这会导致进入应用程序时出现延迟,并且不会显示应用程序已开始执行。什么可能导致这种行为以及如何尽可能顺利地初始化应用程序?

1 个答案:

答案 0 :(得分:1)

提供您正在寻找的效果不是AMD语义的一部分。您唯一的保证是,传递给require的回调不会运行,直到依赖于回调的依赖关系数组中列出的模块及其依赖项被加载。

RequireJS无法很好地控制浏览器如何将请求发送到服务器。例如,如果发生这种情况,那么当您发出请求时,浏览器已经有太多其他待处理请求(对于样式表,图像或其他必须加载的内容,除了您通过require要求的模块之外),浏览器可能决定延迟RequireJS'直到先前的请求得到解决。

如何在服务器端解析请求也会影响将以什么顺序发生的事情。

然后是您的应用程序的结构。假设main.config().modules包含['A', 'B', 'C']。因此,您希望按顺序加载ABC并让它们尽快初始化。然而,事实证明所有这些模块也依赖于jquery。当RequireJS执行A时,它会运行define(['jquery], function ($) {...。好的,现在必须提取jquery。在提取jquery时,BC也可能会等待它。因此,RequireJS将执行ABC以及以接近连续的顺序等待它们的回调。只有一个依赖项,它可能不是什么大问题,但如果你的模块依赖于大量其他常见模块,它会加起来,最终结果是你会在加载公共模块时看到明显的等待,然后看起来像{ {1}},AB批量执行。

可以使用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加载后请求等。而在原始代码中,所有模块都是直接请求的。这可能导致总的初始化时间更长。