Можно ли использовать requirejs, когда модули могут быть удалены для экономии памяти - PullRequest
16 голосов
/ 02 июля 2010

Разрабатываем приложение во встроенной среде.Это высокоуровневая вычислительная среда с полным веб-браузером на вершине занятой системы Linux.Единственное исключение состоит в том, что система имеет ограниченный объем системной памяти.

Наше приложение построено на JavaScript и работает в веб-браузере на основе Webkit и состоит из множества модулей JavaScript, которые загружаются последовательно (что являетсяне очень эффективно).

Некоторые модули предоставляют общую функциональность, которая используется несколькими модулями.Мы находимся в процессе преобразования нашего текущего загрузчика javascript с помощью requirejs, но есть одна конкретная потребность, которую мы должны сначала рассмотреть.

Можно ли выгрузить модуль, когда он был загружен с использованием requirejs?Предположим, что мы динамически загружаем модуль, используя:

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

, который хорошо работает для загрузки и запуска somemodule, а также для разрешения всех зависимостей для somemodule, а инфраструктура requirejs будет хранить ссылку на somemodule длябудущие запросы.

Если в какой-то момент нам нужно восстановить память, например, чтобы иметь возможность загружать и запускать бесконечное количество модулей, мы должны начать удалять некоторые из них через некоторое время.Возможно ли это с помощью requirejs без изменения внутренней реализации?

Кто-нибудь сталкивался с подобной проблемой раньше?Большинство одностраничных приложений JS запускаются в веб-браузере на настольном ПК, где использование памяти обычно не является серьезной проблемой.

Ответы [ 2 ]

17 голосов
/ 02 июля 2010

RequireJS не имеет встроенной функции выгрузки, но ее можно добавить, возможно, в качестве дополнительной части, которую вы можете встроить в нее. Если вы хотели бы иметь эту функцию, не стесняйтесь предлагать ее в списке рассылки или в виде GitHub выпуска .

Если вы хотите поэкспериментировать, чтобы выяснить, помогает ли это в вашей ситуации, вам нужно сделать следующее:

1) Удалить определенный модуль из кэша модуля RequireJS. Если вы не используете поддержку многоверсии, вы можете сделать что-то вроде:

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

2) Затем вы можете попробовать удалить тег script, чтобы увидеть, поможет ли это:

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(); } );
2 голосов
/ 09 апреля 2013

Попробуйте это: require.undef (moduleName)

...