2010-07-02 110 views
15

我们在嵌入式环境中开发应用程序。它是一个高级计算环境,在busybox Linux系统的顶部有一个完整的webbrowser。唯一的例外是系统具有有限的系统内存。当需要移除模块以节省内存时,是否可以使用requirejs

我们的应用程序使用JavaScript构建,并在基于Webkit的浏览器中运行,并且包含大量按顺序加载的JavaScript模块(这不是非常高效)。

某些模块提供了几个模块使用的常用功能。我们正在将我们当前的JavaScript加载程序与requirejs进行转换,但有一个具体需求需要我们首先解决。

使用requirejs加载模块时可以卸载它吗?假设我们动态加载使用一个模块:

require(["somemodule.js"], function(m) { m.run(); }); 

,对于加载和运行“somemodule”,同时也解决了“somemodule”所有的依赖和requirejs框架行之有效会参考存储为将来的请求“somemodule” 。

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

有没有人处理过这类问题?大多数单页JS应用程序在桌面PC上的web浏览器中运行,其中内存使用通常不是主要关心的问题。

回答

17

RequireJS没有内置的卸载功能,但可以添加它作为您可以构建到其中的附加部件。如果您想拥有该功能,请随时在the mailing listGitHub issue中提出。

如果你想尝试,看它是否有助于你的情况,你需要做的是以下几点:

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.def来定义自己的模块,它应该像这样(没有后缀名为.js):

require(["somemodule"], function(m) { m.run(); }); 
+0

谢谢,当我测试更多时我会回来。我们仍然使用我们自己的脚本加载器,但会转换为requirejs,因为应用程序当前使用全局名称空间,所以还有一些重构。 我在requirejs的源代码中注意到onScriptLoad不会删除scriptTag,但是您建议在上面的答案中这样做。 是否出于性能原因scriptTag保存在requirejs中的DOM树中?例如,因为删除脚本会在加载器中增加一些额外的处理。 我们的预加载器总是删除onload回调中的scriptTag以保留内存。 – Ernelli 2010-07-04 14:01:06

+0

我不删除脚本标记以使调试变得更容易(我的脚本真的加载了吗?从哪里来?)并且还试图减小加载器代码的大小。我觉得不会有太多的节省,特别是在HTML中内嵌脚本标签的页面上。不过,我会记录下来测试它是否有所作为,并且可以跨浏览器使用。您指出它确实有所作为,也许我应该提供一个选项来做到这一点。有关如何验证内存节省的任何信息,我都赞赏。 – jrburke 2010-07-05 04:35:32

+2

我们在嵌入式系统中使用的浏览器(IPTV机顶盒)基于Webkit。即使从文档中删除脚本标签,异常的来源等也被正确标记。 我不得不做一些更多的测试,看看有多少scriptTag去除会影响内存使用情况。即使当scriptTags被移除时,JS引擎也能够重新创建给定函数的源代码(尽管没有注释)。 我们根据监控系统中可用内存的数量来完成我们所有的内存分析。 – Ernelli 2010-07-05 08:06:37

2

试试这个:require.undef(moduleName)

+2

from undef:“[...]但是,它不会从已经定义的其他模块中移除该模块,并且在执行时将该模块的句柄当作依赖项,所以它只对在没有其他模块获得模块值的句柄时在错误情况下使用“ – Steen 2013-06-27 20:36:46

相关问题