【问题标题】:Why does require.js seem to be loading all my modules on initial page load?为什么 require.js 似乎在初始页面加载时加载了我的所有模块?
【发布时间】:2012-08-06 13:51:30
【问题描述】:

我正在使用 requirejs 开发一个单页面主干应用程序,今天当我部署到我们的测试版服务器时,我发现初始页面加载大约需要 20 秒,同时它会获取所有脚本。

我认为这是因为我在定义模块时使用了依赖数组:

define([
    'ui',
    'models/user',
    'collections/campaigns',
    'collections/groups',
    'collections/keywords',
    'collections/inboxes',
    'collections/templates',
    'collections/contacts',
    'router'
], function (Ui, UserDetails, Campaigns, Groups, Keywords, Inboxes, Templates, Contacts, Router) {

    return {
        start: function () {
            // ...
            // initialize and start app
            // ...
        }
    }
});

我认为这意味着当加载主应用程序模块时,将加载所有其他脚本,因为每个单独的模块都使用这种方法。

然后我更改了获取模块的方法,以便在需要时直接调用require('...') 来获取它们,如下所示:

define(function (require) {
    return Backbone.Router(function () {
        // ...
        // route initializtion etc
        // ...

        inbox: function (routeVar) {
            var InboxView = require('InboxView');
            this.inboxView = new InboxView();
            // render view etc
        }
    });
});

但令我惊讶的是,在再次运行应用程序并检查 chromes 开发者控制台的网络选项卡时 - 我看到应用程序正在获取我的所有模块,并且我得到了相同的页面加载时间。

我是否完全错过了这里的重点?因为我的印象是每次调用 require 时都会获取脚本。不对吗?

【问题讨论】:

    标签: javascript backbone.js requirejs


    【解决方案1】:

    为了异步加载 AMD 模块,您必须调用 require 并提供一个函数回调,当请求的模块已加载时将调用该回调函数:

    require(['InboxView'], function(InboxView) {
      // Do something with InboxView here...
    });
    

    您提供的示例代码以同步方式命名为require('InboxView')。因为您使用的是“sugar”语法,RequireJS 将检查您的代码,找到对require() 的任何同步调用,并将这些依赖项添加到模块的顶级依赖项列表中,实际上为您提供:

    define(['require', 'InboxView'], function (require) {
      return Backbone.Router(function () {
        // ...
        // route initializtion etc
        // ...
    
        inbox: function (routeVar) {
            var InboxView = require('InboxView');
            this.inboxView = new InboxView();
            // render view etc
        }
      });
    });
    

    ...因此您看到所有模块立即加载。

    将异步回调添加到要求,你应该没问题。另外,如果您考虑一下,如果 RequireJS 等待为 InboxView 加载模块,直到您的路由被触发而 require 调用阻塞直到加载完成,您的代码将如何工作? :)

    【讨论】:

    • 好吧,我实际上认为它会在加载脚本时阻塞,感谢您提供的信息,我会调查一下
    • 为回复欢呼,按照您的建议执行异步请求解决了我的问题。我现在已经大大减少了我的初始页面加载。非常感谢!
    • "['require', 'InboxView']" 是什么意思?我从来没有见过这样的事情。谢谢。
    • @VladNicula Requiring require 告诉 requireJS 为模块提供适当范围的 require 函数实例,它可以使用它来请求更多模块。如果您使用multi-version support 之类的东西,那么正确的范围界定很重要,因此需要加载请求模块的正确版本。在这个特定的例子中,由于使用了sugar syntax,requireJS 自动生成了所需模块的列表。
    • @dormisher 您能否详细说明您的最终解决方案是什么?我已经尝试过上面的代码,a)它不起作用,因为没有语法 require('InboxView', function(InboxView) {}) 和 b)从概念上讲,没有“同步”需求调用之类的东西。所有 require 调用都是异步的。
    猜你喜欢
    • 2012-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-08
    • 1970-01-01
    • 2015-08-23
    • 2013-05-08
    • 2012-07-31
    相关资源
    最近更新 更多