Quelle est la bonne façon de détruire une Instance Map?

j'ai récemment développé une application mobile html5. L'application était une page unique où les événements de changement de hachage de navigation ont remplacé le DOM entier. Une section de L'application était une carte Google utilisant API v3. Avant que le div map ne soit retiré du DOM, je veux supprimer tous les gestionnaires d'événements/auditeurs et libérer autant de mémoire que possible car l'utilisateur ne peut pas retourner à cette section à nouveau.

Quelle est la meilleure façon de détruire une instance map?

81
demandé sur epignosisx 2012-05-07 20:23:37

7 réponses

j'ajoute une deuxième réponse à cette question, parce que je ne veux pas enlever les Va-et-vient que nous avons eu via des commentaires de suivi sur ma réponse précédente.

mais je suis tombé récemment sur quelques informations qui répondent directement à votre question et donc je voulais partager. Je ne sais pas si vous êtes au courant de cela, mais pendant le Google Maps heures de bureau de L'API 9 mai 2012 vidéo , Chris Broadfoot et Luke Mahe de Google a discuté très question de stackoverflow. Si vous mettez la lecture vidéo à 12:50, c'est la section où ils discutent de votre question.

essentiellement, ils admettent que c'est un bug, mais ajoutent aussi qu'ils ne supportent pas vraiment les cas d'utilisation qui impliquent de créer/détruire des instances de map successives. Ils recommandent fortement de créer une instance unique de la carte et de la réutiliser dans n'importe quel scénario de ce genre. Ils parlent aussi de définir la map à null, et explicitement supprimer auditeurs d'événements. Vous avez exprimé des préoccupations au sujet des auditeurs de l'événement, je pensais qu'il suffirait de régler la carte à null, mais il semble que vos préoccupations sont valables, parce qu'elles mentionnent spécifiquement les auditeurs de l'événement. Ils ont également recommandé de supprimer complètement le DIV qui détient également la carte.

en tout cas, je voulais juste transmettre ceci et s'assurer qu'il est inclus dans la discussion stackoverflow et j'espère qu'il vous aide et d'autres -

45
répondu Sean Mickey 2018-10-04 19:27:46

the official answer is you don'T. Les cas de mappage dans une application d'une seule page devraient être réutilisés et non détruits puis recréés.

pour certaines applications d'une seule page, cela peut signifier une nouvelle architecture de la solution telle qu'une fois qu'une carte est créée, elle peut être cachée ou déconnectée du DOM, mais elle n'est jamais détruite/recréée.

24
répondu Chad Killingsworth 2017-08-11 10:27:18

puisqu'apparemment vous ne pouvez pas vraiment détruire les instances de carte, un moyen de réduire ce problème si

  • vous devez afficher plusieurs cartes à la fois sur un site web
  • le nombre de cartes peut changer avec l'interaction de l'utilisateur
  • les cartes doivent être cachées et re-montrées avec d'autres composants (c'est-à-dire qu'elles n'apparaissent pas dans une position fixe dans le DOM)

tient un pool de cartes instance. La piscine garde des pistes d'instances utilisées, et quand il est demandé une nouvelle instance, il vérifie si la carte disponible instances est gratuit: si il l'est, il sera de retour un existant, si elle n'est pas, il va créer une nouvelle carte de l'instance et de la retourner, ajoutant à la piscine. De cette façon, vous n'aurez qu'un nombre maximal d'instances égal au nombre maximum de cartes que vous jamais afficher simultanément sur l'écran. J'utilise ce code (il nécessite jQuery):

var mapInstancesPool = {
 pool: [],
 used: 0,
 getInstance: function(options){
    if(mapInstancesPool.used >= mapInstancesPool.pool.length){
        mapInstancesPool.used++;
        mapInstancesPool.pool.push (mapInstancesPool.createNewInstance(options));
    } else { 
        mapInstancesPool.used++;
    }
    return mapInstancesPool.pool[mapInstancesPool.used-1];
 },
 reset: function(){
    mapInstancesPool.used = 0;
 },
 createNewInstance: function(options){
    var div = $("<div></div>").addClass("myDivClassHereForStyling");
    var map =   new google.maps.Map(div[0], options);
    return {
        map: map,
        div: div
    }
 }
}

vous lui passez les options de carte de départ (selon le deuxième argument de google.cartographie.Map's constructor), et il renvoie à la fois l'instance map (sur laquelle vous pouvez appeler les fonctions relatives à google.cartographie.Carte), et le conteneur, que vous pouvez styliser en utilisant la classe "myDivClassHereForStyling", et vous pouvez dinamically ajouter au DOM. Si vous avez besoin de réinitialiser le système, vous pouvez utiliser mapintancespool.réinitialiser.)( Cela réinitialise le compteur à 0, tout en gardant toutes les instances existantes dans la piscine pour réutiliser. Dans mon application, j'ai dû supprimer toutes les cartes à la fois et créer un nouvel ensemble de cartes, donc il n'y a pas de fonction pour recycler une instance de carte spécifique: votre kilométrage peut varier. Pour enlever les cartes de l'écran, j'utilise le détachant de jQuery, qui ne détruit pas le conteneur de la carte .

en utilisant ce système, et en utilisant

google.maps.event.clearInstanceListeners(window);
google.maps.event.clearInstanceListeners(document);

et en cours d'exécution

google.maps.event.clearInstanceListeners(divReference[0]);
divReference.detach()

(où divReference est l'objet jQuery de la div Exemple De La Piscine) sur chaque div que je supprime, j'ai réussi à maintenir L'utilisation de la mémoire de Chrome plus ou moins stable, au lieu de l'augmenter chaque fois que je supprime des cartes et en ajoute de nouvelles.

11
répondu Paolo Mioni 2014-08-27 17:08:39

j'aurais suggéré de supprimer le contenu de la map div et d'utiliser delete sur la variable contenant la référence à la map, et probablement explicitement delete dans tous les écouteurs d'événements.

il y a un bogue reconnu , cependant, et cela pourrait ne pas fonctionner.

5
répondu Andrew Leach 2012-05-07 17:13:01

comme google ne fournit pas gunload () pour api v3 mieux utiliser iframe en html et attribuer une carte.html comme source de cette iframe. après utilisation faites src comme null. Cela libérera définitivement la mémoire consommée par map.

2
répondu kumar 2013-08-23 06:39:52

lorsque vous supprimez le div , qui supprime le panneau d'affichage et la carte disparaîtra. Pour supprimer l'instance map, assurez-vous que votre référence à la carte est définie à null et que toute référence à d'autres parties de la carte est définie à null . À ce moment-là, la collecte des ordures JavaScript s'occupera du nettoyage, tel que décrit dans: Comment fonctionne la collecte des ordures en JavaScript? .

1
répondu Sean Mickey 2017-05-23 12:02:22

je suppose que vous parlez de addEventListener . Lorsque vous supprimez les éléments DOM, certains navigateurs fuient ces événements et ne les suppriment pas. C'est pourquoi jQuery fait plusieurs choses en enlevant un élément:

  • il supprime les événements quand il peut utiliser removeEventListener . Cela signifie qu'il garde un tableau avec les écouteurs d'événements qu'il a ajouté sur cet élément.
  • supprime les attributs concernant les événements ( onclick , onblur , etc.) en utilisant delete sur L'élément DOM quand addEventListener n'est pas disponible (encore, il a un tableau où il stocke les événements ajoutés).
  • définit l'élément à null pour éviter les fuites de mémoire IE 6/7/8.
  • il supprime alors l'élément.
0
répondu Florian Margaine 2012-05-07 17:08:52