当可能必须删除模块以节省内存时,是否可以使用requirejs

Ern*_*lli 16 javascript memory-management module requirejs

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

我们的应用程序是用JavaScript构建的,并在基于Webkit的webbrowser中运行,并且包含许多按顺序加载的javascript模块(效率不高).

某些模块提供了多个模块使用的通用功能.我们正在使用requirejs转换当前的javascript加载器,但我们必须先解决一个特定的需求.

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

require(["somemodule.js"], function(m) { m.run(); } );
Run Code Online (Sandbox Code Playgroud)

这适用于加载和运行'somemodule'并且还解决'somemodule'的所有依赖关系,而requirejs框架将存储对'somemodule'的引用以用于将来的请求.

如果我们在某些时候需要回收内存,例如能够加载和运行无限数量的模块,我们必须在一段时间后开始删除其中的一些.这是否可以使用requirejs而不改变内部实现?

有没有人以前处理过这类问题?大多数单页JS应用程序在台式PC上的Web浏览器中运行,其中内存使用通常不是主要问题.

jrb*_*rke 17

RequireJS没有内置的卸载功能,但它可能会作为您可以构建到其中的附加部分添加.如果您想拥有该功能,请随时在邮件列表中提出或作为GitHub问题提出.

如果您想尝试查看它是否有助于您的情况,您需要做的是以下内容:

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

var context = require.s.contexts['_'];
delete context.defined[moduleName];
delete context.specified[moduleName];
delete context.loaded[moduleName];
Run Code Online (Sandbox Code Playgroud)

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,如果另一个模块通过定义该其他模块的闭包函数(){}来保持该模块,则该模块可能不会被垃圾收集.那个其他模块也需要删除.

您可以尝试通过不将模块作为函数参数传递来限制该影响,但只要在函数定义中使用require("somemodule"),只要您想要获取依赖模块,而不是坚持需要返回价值太久了.

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

require(["somemodule"], function(m) { m.run(); } );
Run Code Online (Sandbox Code Playgroud)

  • 我们在嵌入式系统(IPTV机顶盒)中使用的浏览器基于Webkit.即使从文档中删除了脚本标记,也会正确标记异常等的来源.我必须做一些测试,看看有多少scriptTag删除会影响内存使用.即使删除了scriptTags,JS引擎也能够为给定的函数重新创建源代码(尽管没有注释).我们基于监视系统中的可用内存量来执行所有内存分析. (2认同)