Javascript 当需要删除模块以节省内存时,是否可以使用requirejs

Javascript 当需要删除模块以节省内存时,是否可以使用requirejs,javascript,memory-management,module,requirejs,Javascript,Memory Management,Module,Requirejs,我们在嵌入式环境中开发了一个应用程序。它是一个高级计算环境,在busybox Linux系统之上有一个完整的webbrowser。唯一的例外是系统内存有限 我们的应用程序是在JavaScript中构建的,在基于Webkit的webbrowser中运行,由许多按顺序加载的JavaScript模块组成(这不是很有效) 一些模块提供多个模块使用的通用功能。我们正在使用requirejs转换当前的javascript加载程序,但是有一个特定的需求我们必须首先解决 使用requirejs加载模块后,是否可

我们在嵌入式环境中开发了一个应用程序。它是一个高级计算环境,在busybox Linux系统之上有一个完整的webbrowser。唯一的例外是系统内存有限

我们的应用程序是在JavaScript中构建的,在基于Webkit的webbrowser中运行,由许多按顺序加载的JavaScript模块组成(这不是很有效)

一些模块提供多个模块使用的通用功能。我们正在使用requirejs转换当前的javascript加载程序,但是有一个特定的需求我们必须首先解决

使用requirejs加载模块后,是否可以卸载模块?假设我们使用以下方法动态加载模块:

require(["somemodule.js"], function(m) { m.run(); } );
这对于加载和运行“somemodule”以及解析“somemodule”的所有依赖项都很有效,并且requirejs框架将存储对“somemodule”的引用以供将来的请求使用

如果我们在某个时候需要回收内存,例如为了能够加载和运行无限多的模块,我们必须在一段时间后开始删除其中的一些模块。在不改变内部实现的情况下,使用requirejs是否可以做到这一点


以前有人处理过这种问题吗?大多数单页JS应用程序在桌面PC上的webbrowser中运行,内存使用通常不是主要问题。

RequireJS没有内置的卸载功能,但可能可以添加它,作为您可以内置的附加部分。如果您想拥有该功能,可以在中或作为一个应用程序提出

如果你想尝试一下,看看它是否有助于你的处境,你需要做的是:

1) 从RequireJS模块缓存中删除定义的模块。如果不使用多版本支持,可以执行以下操作:

var context = require.s.contexts['_'];
delete context.defined[moduleName];
delete context.specified[moduleName];
delete context.loaded[moduleName];
2) 然后,您可以尝试删除脚本标记,看看这是否有帮助:

var scripts = document.getElementsByTagName('script');
for (var i = scripts.length - 1; i >= 0; i--) {
    var script = scripts[i];
    if (script.getAttribute('data-requiremodule') === moduleName) {
        script.parentNode.removeChild(script);
        break;
    }
}
请注意,如果另一个模块通过定义该另一个模块的闭包函数(){}持有该模块,则该模块可能不会被垃圾收集。另一个模块也需要拆除

您可以尝试通过不将模块作为函数参数传入来限制这种影响,但只要在函数定义中使用require(“somemodule”),就可以获得依赖模块,而不需要将require返回值保留太长时间

另外,在上面的示例中,对于使用require.def定义自己的模块,应该是这样的(没有.js后缀):


试试这个:

谢谢,等我再测试一遍后,我会回来的。我们仍然使用自己的脚本加载器,但将转换为requirejs,因为应用程序当前使用全局名称空间,所以需要进行一些重构。我在requirejs的源代码中注意到onScriptLoad并没有删除scriptTag,但在上面的回答中建议这样做。是否出于性能原因,scriptTag保留在requirejs中的DOM树中?例如,由于删除scriptag会在加载程序中添加一些额外的处理。我们的预加载程序总是删除onload回调中的scriptTag以保留内存。我删除script tag不是为了使调试更容易(我的脚本真的加载了吗?从哪里加载?),而是为了尽量减小加载程序代码的大小。我认为不会有太多的节省,尤其是在HTML中内联了脚本标记的页面上。然而,我将做一个注释来测试删除它是否有区别,并且它可以跨浏览器工作。你表示这确实会有所不同,也许我应该提供一个选项来做。我们非常感谢您提供有关如何验证内存节省的任何信息。我们在嵌入式系统(IPTV机顶盒)中使用的浏览器基于Webkit。即使从文档中删除ScriptTag,也会正确标记异常等的起源。我确实需要做更多的测试,看看scriptTag的删除对内存使用的影响有多大。即使删除了ScriptTag,JS引擎也能够为给定函数重新创建源代码(尽管没有注释)。我们在监控系统中的可用内存量的基础上进行所有内存分析。接下来,您必须为每个模块定义一个虚拟析构函数:)我还面临类似的情况,我为我的单页应用加载google map。我真的很想把谷歌和它所有的东西卸载到一个特别的内存中。在最新的requirejs上有什么进展吗?来自undef上的requirejs文档:“[…]但是,它不会从其他已定义的模块中删除该模块,并且在执行时将该模块的句柄作为依赖项。因此,只有在没有其他模块获得模块值句柄的错误情况下,才真正有用。”
require(["somemodule"], function(m) { m.run(); } );