RequireJS:捆绑或不捆绑

时间:2013-12-11 09:45:05

标签: requirejs

我在我的网络应用程序中使用RequireJS。我正在使用EmberJS作为应用程序框架。我想,我应该开始将我的应用程序捆绑到一个单独的js文件中。这是我有点困惑的地方:

如果我最终将所有内容捆绑到一个文件中进行部署,那么我的整个应用程序会一次性加载,而不是按需加载。是不是与AMD有一定的矛盾,尤其是RequireJS?

让我感到困惑的是我在RequireJS网站上找到的内容:

  

完成开发并希望为最终用户部署代码后,您可以使用优化器将JavaScript文件组合在一起并缩小它。在上面的示例中,它可以将main.js和helper / util.js组合到一个文件中并缩小结果。

我发现了这个similar thread,但它没有回答我的问题。

2 个答案:

答案 0 :(得分:20)

  

如果我最终将所有内容捆绑到一个文件中进行部署,那么我的整个应用程序会一次性加载,而不是按需加载。是不是与AMD有一定的矛盾,尤其是RequireJS?

这并不矛盾。按需加载模块只是RequireJS的一个好处。我的书中更大的好处是模块化有助于使用分而治之的方法。我们可以这样看待它:即使我们放在单个文件中的所有函数和类都不能从按需加载中受益,我们仍然会编写多个函数和多个类,因为它有助于以结构化方式分解问题。

但是,在浏览器中运行应用程序时,我们在开发中创建的模块的多样性并不一定有意义。按需加载的最大成本是通过线路发送多个HTTP请求。假设您的应用程序有10个模块,并且您发送10个请求加载它,因为您单独加载这些模块。您的总成本将是从10个文件加载字节所需支付的成本(让我们将其称为Pc用于有效负载成本),加上每个HTTP请求的开销成本(让我们称之为Oc,用于管理费用)。开销与启动和关闭这些请求所必需的数据和计算有关。它们并非无足轻重。所以你付的是Pc + 10 * Oc。如果您将所有内容都发送到一个块中,则需要支付Pc + 1 * Oc。你已经保存了9 * Oc。事实上,节省可能更大,因为(因为压缩通常用于两端以减少传输数据的大小)如果整个数据被压缩在一起,压缩将提供比将其压缩为10个块时更大的好处。 (注意:上述分析省略了无用的细节。)

有人可能会反对:“但是你要比较单独加载所有模块,而不是在一个块中加载所有模块。如果我们按需加载那么我们就赢了” t加载所有模块。“事实上,大多数应用程序都有一个核心模块,无论如何都会被加载。这些是模块,没有它们,应用程序将无法完全。对于一些小型应用程序,这意味着所有模块,因此将所有模块捆绑在一起是有意义的。对于更大的应用程序,这意味着每次运行应用程序时都会使用一组核心模块,但只会偶尔使用一小组模块。在后一种情况下,优化应创建多个包。我有application这样的话。它是一个编辑器,具有各种编辑需求的模式。 90%的模块属于核心。它们将被加载并使用无论如何所以将它们捆绑起来是有意义的。模式本身的代码并不总是会被使用,但是如果模式被加载则需要给定模式的所有文件,因此每个模式应该是它自己的包。因此,在这种情况下,具有一个核心束和一系列模式束的模型对于a)优化已部署的应用程序有意义,但b)保持按需加载的一些好处。这就是RequireJS的美妙之处:它不需要专门做一个或另一个。

答案 1 :(得分:2)

在开发过程中,您希望拥有单一焦点的小文件。这导致他们的数量增加。在生产中运行时,许多HTTP请求确实会损害性能。然后你再次不想预先加载整个应用程序 - 这也不是最佳的。

为了解决这个问题,我在GitHub中创建了一个小项目,require-lazy,你可以将它作为插件调用到构建器--r.js.它可以使用简单的语法延迟加载应用程序的一部分,然后在构建过程中单独创建可加载的bundle;所以如果你的应用程序包含2个需要独立加载的视图,那么require-lazy将(理想情况下)构建3个js文件:(1)引导代码和公共库,(2)查看1及其所有私有脚本和(3) )查看2及其所有私有脚本。

延迟加载简单定义为:

define(["lazy!view1"], function(view1) { .... });

必须使用承诺访问view1

view1.get().done(function(realView1) {
    ...
});

该项目可以通过npm获得,通过grunt构建过程并且有一个bower组件。

非常欢迎评论。