Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to use requirejs when modules may have to be removed to conserve memory

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.

like image 978
Ernelli Avatar asked Jul 02 '10 07:07

Ernelli


People also ask

What is the main purpose of the RequireJS framework?

RequireJS is a JavaScript file and module loader. It improves perceived page load times because it allows JavaScript to load in the background. In particular, it enables asynchronous JavaScript loading.

How do you use RequireJS?

Syntax. define(['module1', 'module2'], function (module1, module2) { //define the module value by returning a value return function () {}; }); You can pass a list of module names when you define a module and RequireJS can be used to retrieve these modules before executing the module.

Is RequireJS asynchronous?

RequireJS, like LABjs, allows for asynchronous JavaScript loading and dependency management; but, RequireJS uses a much more modular approach to dependency definitions. This is just an initial exploration of RequireJS. RequireJS seems to be quite robust and includes optimization and "build" tools for deployment.

What is RequireJS shim?

As per RequireJS API documentation, shim lets you. Configure the dependencies, exports, and custom initialization for older, traditional "browser globals" scripts that do not use define() to declare the dependencies and set a module value.


2 Answers

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(); } );
like image 116
jrburke Avatar answered Nov 15 '22 15:11

jrburke


Try this: require.undef(moduleName)

like image 29
Zzarcon Avatar answered Nov 15 '22 13:11

Zzarcon