草庐IT

javascript - requirejs - 多次调用 require 的性能

coder 2024-12-10 原文

我想知道在具有多个模块的项目中使用 RequireJS 的正确方法是什么,关于具有较少依赖项的多个 require 调用与具有所有依赖项的单个 require 调用的性能。

让我们举个例子,对于一个应用程序,我需要加载一些模块:gmaps、jquery、module1、module2、module3。一些模块的使用是完全独立的。所以,问题是推荐以下哪个替代方案(假设这段代码是加载到页面中的主要模块):

require(['gmaps'], function(gmaps){
   gmaps.use();
});

require(['jquery','module1'], function(jquery, module1){
   module1.use();
});

require(['jquery','module2'], function(jquery, module2){
   module2.use();
});

require(['jquery','module3'], function(jquery, module3){
   module3.use();
});

对比

require(['jquery','module1','module1','module1','gmaps'], function(jquery, module1,module2,module3,gmaps){
   module1.use();
   module2.use();
   module3.use();
   gmaps.use();
});

换句话说,require 的性能损失是多少,哪个是最佳实践。

最佳答案

此处问题的答案是“视情况而定”。我是以在大型应用程序中使用过 RequireJS 但没有彻底阅读 RequireJS 代码的人的身份发言的。 (只是指出了解 RequireJS 内部和外部内部结构的人可能与我的解释不同。)require 的成本可以分为 3 种成本场景:

  1. 如果模块从未加载过,require 从服务器加载文件、执行文件、执行模块的工厂函数并返回对模块的引用。 (从网络加载文件的成本通常使其他成本相形见绌。)

  2. 如果模块已经加载但从未被要求,require 执行模块的工厂函数并返回对模块的引用。 (这通常会发生在优化的应用程序中。)

  3. 如果模块已经被加载并需要,require 返回对模块的引用。

成本方案 1 > 成本方案 2 > 成本方案 3。

首先,让我们考虑每个文件有一个模块的情况。应用程序未优化。我有一个名为 module1 的模块,难得一见。它在主应用程序中的用法可以像这样建模:

define(["module1", <bunch of other required modules>],
    function (module1, <bunch of other modules variables>) {

    [...]

    if (rare_condition_happening_once_in_a_blue_moon)
        module1.use();

    [...]
});

在这里,即使我不使用该模块,我也总是支付成本方案 1 的价格。最好这样做:

define([<bunch of required modules>],
    function (<bunch of module variables>) {

    [...]

    if (rare_condition_happening_once_in_a_blue_moon)
        require(["module1"], function (module1) {
            module1.use();
        });

    [...]
});

这样一来,我将付出加载模块的代价一次千载难逢。

现在,如果我需要重复使用 module 怎么办?这可以建模为:

define(["module1", <bunch of other required modules>],
    function (module1, <bunch of other modules variables>) {

    [...]

    for(iterate a gazillion times)
        module1.use();

    [...]
});

在这种情况下,成本方案 1 只支付一次,仅此而已。如果我像这样使用 require:

define([<bunch of required modules>],
    function (<bunch of module variables>) {

    [...]

    for(iterate a gazillion times)
        require(["module1"], function (module1) {
            module1.use();
        });

    [...]
});

我支付场景 1 一次(无数次 - 1)场景 3 的成本。在一天结束时,module1 是否应该包含在 define 调用的要求中或包含在单独的 require 调用中取决于您的应用程序的具体情况。

如果应用程序已使用 r.js 或自制优化进行了优化,则分析会发生变化。如果应用程序经过优化,所有模块都在一个文件中,则每次您在上述情况下支付成本方案 1 时,您将支付成本方案 2。

为了完整起见,我将补充一点,如果您事先不知道您可能想要加载的模块,则必须使用 require

define([<bunch of other required modules>],
    function (<bunch of other modules variables>) {

    [...]

    require(<requirements unknown ahead of time>, function(m1, m2, ...) {
        m1.foo();
        m2.foo();
        [...]
    });

    [...]
});

关于javascript - requirejs - 多次调用 require 的性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19892601/

有关javascript - requirejs - 多次调用 require 的性能的更多相关文章

  1. ruby - 多次弹出/移动 ruby​​ 数组 - 2

    我的代码目前看起来像这样numbers=[1,2,3,4,5]defpop_threepop=[]3.times{pop有没有办法在一行中完成pop_three方法中的内容?我基本上想做类似numbers.slice(0,3)的事情,但要删除切片中的数组项。嗯...嗯,我想我刚刚意识到我可以试试slice! 最佳答案 是numbers.pop(3)或者numbers.shift(3)如果你想要另一边。 关于ruby-多次弹出/移动ruby​​数组,我们在StackOverflow上找到一

  2. ruby - 主要 :Object when running build from sublime 的未定义方法 `require_relative' - 2

    我已经从我的命令行中获得了一切,所以我可以运行rubymyfile并且它可以正常工作。但是当我尝试从sublime中运行它时,我得到了undefinedmethod`require_relative'formain:Object有人知道我的sublime设置中缺少什么吗?我正在使用OSX并安装了rvm。 最佳答案 或者,您可以只使用“require”,它应该可以正常工作。我认为“require_relative”仅适用于ruby​​1.9+ 关于ruby-主要:Objectwhenrun

  3. ruby - 无法让 RSpec 工作—— 'require' : cannot load such file - 2

    我花了三天的时间用头撞墙,试图弄清楚为什么简单的“rake”不能通过我的规范文件。如果您遇到这种情况:任何文件夹路径中都不要有空格!。严重地。事实上,从现在开始,您命名的任何内容都没有空格。这是我的控制台输出:(在/Users/*****/Desktop/LearningRuby/learn_ruby)$rake/Users/*******/Desktop/LearningRuby/learn_ruby/00_hello/hello_spec.rb:116:in`require':cannotloadsuchfile--hello(LoadError) 最佳

  4. 使用 ACL 调用 upload_file 时出现 Ruby S3 "Access Denied"错误 - 2

    我正在尝试编写一个将文件上传到AWS并公开该文件的Ruby脚本。我做了以下事情:s3=Aws::S3::Resource.new(credentials:Aws::Credentials.new(KEY,SECRET),region:'us-west-2')obj=s3.bucket('stg-db').object('key')obj.upload_file(filename)这似乎工作正常,除了该文件不是公开可用的,而且我无法获得它的公共(public)URL。但是当我登录到S3时,我可以正常查看我的文件。为了使其公开可用,我将最后一行更改为obj.upload_file(file

  5. c# - 如何在 ruby​​ 中调用 C# dll? - 2

    如何在ruby​​中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL

  6. java - 从 JRuby 调用 Java 类的问题 - 2

    我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www

  7. ruby - 调用其他方法的 TDD 方法的正确方法 - 2

    我需要一些关于TDD概念的帮助。假设我有以下代码defexecute(command)casecommandwhen"c"create_new_characterwhen"i"display_inventoryendenddefcreate_new_character#dostufftocreatenewcharacterenddefdisplay_inventory#dostufftodisplayinventoryend现在我不确定要为什么编写单元测试。如果我为execute方法编写单元测试,那不是几乎涵盖了我对create_new_character和display_invent

  8. ruby - 检查是否通过 require 执行或导入了 Ruby 程序 - 2

    如何检查Ruby文件是否是通过“require”或“load”导入的,而不是简单地从命令行执行的?例如:foo.rb的内容:puts"Hello"bar.rb的内容require'foo'输出:$./foo.rbHello$./bar.rbHello基本上,我想调用bar.rb以不执行puts调用。 最佳答案 将foo.rb改为:if__FILE__==$0puts"Hello"end检查__FILE__-当前ruby​​文件的名称-与$0-正在运行的脚本的名称。 关于ruby-检查是否

  9. 【鸿蒙应用开发系列】- 获取系统设备信息以及版本API兼容调用方式 - 2

    在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList​()Obt

  10. C51单片机——实现用独立按键控制LED亮灭(调用函数篇) - 2

    说在前面这部分我本来是合为一篇来写的,因为目的是一样的,都是通过独立按键来控制LED闪灭本质上是起到开关的作用,即调用函数和中断函数。但是写一篇太累了,我还是决定分为两篇写,这篇是调用函数篇。在本篇中你主要看到这些东西!!!1.调用函数的方法(主要讲语法和格式)2.独立按键如何控制LED亮灭3.程序中的一些细节(软件消抖等)1.调用函数的方法思路还是比较清晰地,就是通过按下按键来控制LED闪灭,即每按下一次,LED取反一次。重要的是,把按键与LED联系在一起。我打算用K1来作为开关,看了一下开发板原理图,K1连接的是单片机的P31口,当按下K1时,P31是与GND相连的,也就是说,当我按下去时

随机推荐