2010-07-02 3 views
15

Nous développons une application dans un environnement intégré. C'est un environnement informatique de haut niveau avec un navigateur web complet sur un système Linux busybox. La seule exception est que le système dispose d'une quantité limitée de mémoire système.Est-il possible d'utiliser requirejs lorsque des modules doivent être retirés pour économiser de la mémoire?

Notre application est construite en JavaScript et tourne à l'intérieur d'un webbrowser basé sur Webkit et se compose de beaucoup de modules javascript qui sont chargés en séquence (ce qui n'est pas très efficace).

Certains modules fournissent des fonctionnalités communes utilisées par plusieurs modules. Nous sommes en train de convertir notre loader javascript actuel avec requirejs, mais il y a un besoin spécifique auquel nous devons répondre en premier.

Est-il possible de décharger un module lorsqu'il a été chargé en utilisant requirejs? Supposons que nous charge dynamiquement un module en utilisant:

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

Cela fonctionne bien pour le chargement et l'exécution « UnModule » et résoudre aussi toutes les dépendances pour « UnModule » et le cadre de requirejs va stocker une référence à « UnModule » pour les futures demandes . Si, à un moment donné, nous avons besoin de récupérer de la mémoire, par exemple pour pouvoir charger et exécuter un nombre infini de modules, nous devons commencer à supprimer certains d'entre eux après un certain temps. Est-ce possible avec requirejs sans modifier l'implémentation interne?

Est-ce que quelqu'un a traité ce genre de problème avant? La plupart des applications JS d'une seule page s'exécutent dans un navigateur Web sur un PC de bureau où l'utilisation de la mémoire n'est généralement pas une préoccupation majeure.

Répondre

17

RequireJS n'a pas de fonctionnalité de déchargement intégrée, mais il pourrait être ajouté peut-être en tant que partie supplémentaire que vous pourriez intégrer dans le système. Si vous souhaitez avoir cette fonctionnalité, n'hésitez pas à la proposer en the mailing list ou en GitHub issue.

Si vous voulez expérimenter pour voir si elle aide votre situation, ce que vous devez faire est la suivante:

1) Retirez le module défini à partir du cache de module RequireJS. Si vous n'utilisez pas le support multiversion, vous pouvez faire quelque chose comme:

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

2) Ensuite, vous pouvez essayer de supprimer la balise de script pour voir si cela aide:

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

Notez que le module peut ne pas être collecté si un autre module s'y accroche via la fonction de fermeture() {} qui définit cet autre module. Cet autre module devrait également être supprimé.

Vous pouvez essayer de limiter cet impact en ne passant pas le module en argument de fonction, mais en utilisant simplement require ("somemodule") dans la définition de la fonction chaque fois que vous souhaitez conserver des modules dépendants. à qui nécessitent une valeur de retour trop longue.

également, dans votre exemple ci-dessus, pour les modules qui utilisent require.def pour se définir, il devrait ressembler à ceci (sans le suffixe .js):

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

Merci , Je reviendrai quand je l'ai testé plus.Nous utilisons toujours notre propre script loader mais nous allons convertir en requirejs, il y a quelques refactoring à venir car l'application utilise actuellement un espace de nommage global. J'ai remarqué dans la source pour requirejs que le onScriptLoad ne supprime pas le scriptTag, mais vous recommande de le faire dans votre réponse ci-dessus. Est-ce pour des raisons de performances que le scriptTag est conservé dans l'arborescence DOM dans requirejs? Par exemple, la suppression des scripts ajouterait un traitement supplémentaire dans le chargeur. Notre préchargeur supprime toujours le scriptTag dans le rappel onload pour préserver la mémoire. – Ernelli

+0

Je ne supprime pas la balise de script pour faciliter le débogage (mon script se charge-t-il vraiment? D'où?) Et essaie également de réduire la taille du code du chargeur. Je pensais qu'il n'y aurait pas beaucoup d'économies en particulier sur une page qui avait les balises de script en ligne dans le HTML. Cependant, je vais faire une note pour tester si cela fait une différence pour l'enlever, et cela fonctionne à travers les navigateurs. Vous indiquez que cela fait une différence, peut-être que je devrais fournir une option pour le faire. Toute information sur la façon dont vous validez les économies de mémoire est appréciée. – jrburke

+2

Le navigateur que nous utilisons dans notre système embarqué (un décodeur IPTV) est basé sur Webkit. Même lorsque les balises de script sont supprimées du document, les origines des exceptions sont correctement étiquetées. Je dois faire d'autres tests pour voir à quel point la suppression de scriptTag affecte l'utilisation de la mémoire. Même lorsque les scriptTags sont supprimés, les moteurs JS sont capables de recréer le code source pour une fonction donnée (bien que sans commentaires). Nous effectuons tous nos profils de mémoire en fonction de la quantité de mémoire disponible dans le système. – Ernelli

2
+2

de la documentation requirejs sur undef: "[...] Cependant, il ne supprimera pas le module des autres modules déjà définis et aura un handle sur ce module en tant que dépendance lors de leur exécution. utiliser dans des situations d'erreur quand aucun autre module n'a un handle sur une valeur de module " – Steen

Questions connexes