2010-07-02 13 views
15

Desarrollamos una aplicación en un entorno incrustado. Es un entorno informático de alto nivel con un navegador web completo en la parte superior de un sistema busybox Linux. La única excepción es que el sistema tiene una cantidad limitada de memoria del sistema.¿Es posible usar requirejs cuando los módulos pueden tener que ser eliminados para conservar memoria?

Nuestra aplicación está construida en JavaScript y se ejecuta dentro de un webbrowser basado en Webkit y consta de una gran cantidad de módulos de JavaScript que se cargan en secuencia (lo cual no es muy eficiente).

Algunos módulos proporcionan una funcionalidad común que utilizan varios módulos. Estamos en el proceso de convertir nuestro cargador de JavaScript actual con requirejs, pero hay una necesidad específica que tenemos que abordar primero.

¿Es posible descargar un módulo cuando se ha cargado usando requirejs? Supongamos que de forma dinámica las cargas de un módulo usando:

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

que funciona bien para cargar y ejecutar 'somemodule' y resolver todas las dependencias para 'somemodule' y el marco RequireJS almacenará una referencia a 'somemodule' para futuras solicitudes .

Si en algún momento necesitamos reclamar memoria, por ejemplo para poder cargar y ejecutar un número infinito de módulos, tenemos que comenzar a eliminar algunos de ellos después de un tiempo. ¿Es posible con requirejs sin alterar la implementación interna?

¿Alguien ha enfrentado este tipo de problema anteriormente? La mayoría de las aplicaciones JS de una sola página se ejecuta en un navegador web en una PC de escritorio donde el uso de memoria no suele ser una preocupación importante.

Respuesta

17

RequireJS no tiene una característica de descarga integrada, pero podría agregarse quizás como una parte adicional que podría incorporar. Si desea tener esa característica, siéntase libre de proponerla en the mailing list o como GitHub issue.

Si quieres experimentar para ver si ayuda a su situación, lo que hay que hacer es la siguiente:

1) Retire el módulo definido desde la caché del módulo RequireJS. Si no está utilizando el soporte multiversión, se puede hacer algo como:

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

2) A continuación, puede intentar quitar la etiqueta script para ver si eso ayuda:

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

Tenga en cuenta que el módulo puede no se recogerá basura si otro módulo se aferra a ella a través de la función de cierre() {} que define ese otro módulo. Ese otro módulo necesitaría ser eliminado también.

Puede intentar limitar ese impacto no pasando el módulo como un argumento de función, sino simplemente use require ("somemodule") dentro de la definición de función siempre que quiera obtener módulos dependientes y no retener para eso requieren un valor de retorno por demasiado tiempo.

Además, en el ejemplo anterior, para los módulos que utilizan require.def a definirse a sí mismos, se debe tener este aspecto (sin el sufijo .js):

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

Gracias , Volveré cuando lo haya probado más.Todavía usamos nuestro propio gestor de carga pero lo convertiremos en requirejs, hay algunas refactorizaciones por delante dado que la aplicación actualmente usa un espacio de nombres global. Observé en el código fuente de requirejs que el onScriptLoad no elimina el scriptTag, pero usted recomienda hacerlo en su respuesta anterior. ¿Es por motivos de rendimiento que scriptTag se mantiene en el árbol DOM en requirejs? Por ejemplo, desde la eliminación de scriptag agregaría algo de procesamiento adicional en el cargador. Nuestro preloader siempre elimina el scriptTag en la devolución de llamada de onload para preservar la memoria. – Ernelli

+0

No elimino la etiqueta del script para facilitar la depuración (¿realmente cargó mi script? ¿Desde dónde?) Y también para mantener el tamaño del código del cargador. Pensé que no habría muchos ahorros, especialmente en una página que tenía las etiquetas de script en línea en el HTML. Sin embargo, escribiré una nota para probar si hace una diferencia eliminarla, y funciona en todos los navegadores. Usted indica que hace una diferencia, tal vez debería proporcionar una opción para hacerlo. Se agradece cualquier información sobre cómo validar los ahorros de memoria. – jrburke

+2

El navegador que utilizamos en nuestro sistema integrado (un conjunto de ajustes de IPTV) se basa en Webkit. Incluso cuando los scripttags se eliminan del documento, los orígenes de las excepciones, etc. están etiquetados correctamente. Tengo que hacer algunas pruebas más para ver cuánto la eliminación de ScriptTag afecta el uso de la memoria. Incluso cuando se eliminan scriptTags, el motor JS puede volver a crear el código fuente para una función determinada (aunque sin comentarios). Hacemos todos nuestros perfiles de memoria basados ​​en el control de la cantidad de memoria libre en el sistema. – Ernelli

2
+2

de la documentación requirejs en undef: "[...] Sin embargo, no eliminará el módulo de otros módulos que ya están definidos y obtuvo un control sobre ese módulo como una dependencia cuando se ejecutaron. Por lo tanto, realmente solo es útil para utilizar en situaciones de error cuando ningún otro módulo tiene un control sobre el valor de un módulo " – Steen

Cuestiones relacionadas