문제

We develop an application in an embedded environment. It is a high level computing environment with a complete webbrowser on top of a busybox Linux system. The only exception is that the system has a limited amount of system memory.

Our application is built in JavaScript and runs inside a Webkit based webbrowser and consists of a lot of javascript modules that are loaded in sequence (Which is not very efficient).

Some modules provide common functionality that is used by several modules. We are in the process of converting our current javascript loader with requirejs, but there is one specific need we have to address first.

Is it possible to unload a module when it has been loaded using requirejs? Assume that we dynamically loads a module using :

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

That works well for loading and running 'somemodule' and also resolving all dependencies for 'somemodule' and the requirejs framework will store a reference to 'somemodule' for future requests.

If we at some point need to reclaim memory, e.g to be able to load and run an infinite number of modules, we have to start removing some of them after some time. Is that possible with requirejs without altering the internal implementation?

Has anyone dealt with this kind of problem before? Most single page JS apps runs in a webbrowser on a desktop PC where memory usage usually is not a major concern.

도움이 되었습니까?

해결책

RequireJS does not have a built-in unload feature, but it could be added perhaps as an additional part you could build into it. If you would like to have that feature, feel free to propose it in the mailing list or as a GitHub issue.

If you wanted to experiment to see if it helps your situation, what you need to do is the following:

1) Remove the defined module from the RequireJS module cache. If you are not using the multiversion support, you can do something like:

var context = require.s.contexts['_'];
delete context.defined[moduleName];
delete context.specified[moduleName];
delete context.loaded[moduleName];

2) Then you can try removing the script tag to see if that helps:

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;
    }
}

Note that the module may not be garbage collected if another module holds on to it via the closure function(){} that defines that other module. That other module would need to be removed too.

You can try to limit that impact by not passing in the module as a function argument, but just use require("somemodule") inside the function definition whenever you want to get a hold of dependent modules, and not holding on to that require return value for too long.

Also, in your example above, for modules that use require.def to define themselves, it should look like this (without the .js suffix):

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

다른 팁

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top