Si un élément DOM est supprimé, ses écouteurs sont-ils également supprimés de la mémoire?
la source
Si un élément DOM est supprimé, ses écouteurs sont-ils également supprimés de la mémoire?
JavaScript simple
Si un élément DOM qui est supprimé est sans référence (aucune référence pointant vers lui), alors oui - l'élément lui-même est récupéré par le garbage collector ainsi que tous les gestionnaires d'événements / écouteurs qui lui sont associés.
var a = document.createElement('div');
var b = document.createElement('p');
// Add event listeners to b etc...
a.appendChild(b);
a.removeChild(b);
b = null;
// A reference to 'b' no longer exists
// Therefore the element and any event listeners attached to it are removed.
Toutefois; s'il existe des références qui pointent toujours vers ledit élément, l'élément et ses écouteurs d'événements sont conservés en mémoire.
var a = document.createElement('div');
var b = document.createElement('p');
// Add event listeners to b etc...
a.appendChild(b);
a.removeChild(b);
// A reference to 'b' still exists
// Therefore the element and any associated event listeners are still retained.
jQuery
Il serait juste de supposer que les méthodes pertinentes dans jQuery (comme remove()
) fonctionneraient exactement de la même manière (considérant que cela a remove()
été écrit en utilisant removeChild()
par exemple).
Cependant, ce n'est pas vrai ; la bibliothèque jQuery a en fait une méthode interne (qui n'est pas documentée et qui peut en théorie être modifiée à tout moment) appelée cleanData()
(voici à quoi ressemble cette méthode ) qui nettoie automatiquement toutes les données / événements associés à un élément lors de sa suppression du DOM que ce soit (par. remove()
, empty()
, html("")
etc.).
Les navigateurs plus anciens - en particulier les anciennes versions d'IE - sont connus pour avoir des problèmes de fuite de mémoire en raison des écouteurs d'événements qui gardent des références aux éléments auxquels ils étaient attachés.
Si vous souhaitez une explication plus approfondie des causes, des modèles et des solutions utilisés pour corriger les fuites de mémoire de versions IE héritées, je vous recommande vivement de lire cet article MSDN sur la compréhension et la résolution des modèles de fuite d'Internet Explorer.
Quelques autres articles pertinents à ce sujet:
La suppression manuelle des écouteurs serait probablement une bonne habitude à prendre dans ce cas (uniquement si la mémoire est vitale pour votre application et que vous ciblez réellement de tels navigateurs).
remove
méthode. la plupart du temps, le DOM sera tout simplement effacé. (comme des liens turbo ou quelque chose). Je me demande comment la mémoire est affectée si je le faisdocument.body.innerHTML = ''
...concernant jQuery:
Référence: http://api.jquery.com/remove/
Code
.remove()
source de jQuery v1.8.2 :apparemment jQuery utilise
node.removeChild()
Selon ceci: https://developer.mozilla.org/en-US/docs/DOM/Node.removeChild ,
The removed child node still exists in memory, but is no longer part of the DOM. You may reuse the removed node later in your code, via the oldChild object reference.
c'est-à-dire que les écouteurs d'événements peuvent être supprimés, mais
node
existent toujours en mémoire.la source
removeChild
cela. Les deux vous renvoient également une référence que vous pouvez conserver pour rattacher cette dernière (auquel cas elle reste évidemment en mémoire) ou la jeter (auquel cas elle est finalement récupérée par GC et supprimée).N'hésitez pas à regarder le tas pour voir les fuites de mémoire dans les gestionnaires d'événements gardant une référence à l'élément avec une fermeture et l'élément gardant une référence au gestionnaire d'événements.
Le garbage collector n'aime pas les références circulaires.
Cas de fuite de mémoire habituel: admettre qu'un objet a une référence à un élément. Cet élément a une référence au gestionnaire. Et le gestionnaire a une référence à l'objet. L'objet a des références à beaucoup d'autres objets. Cet objet faisait partie d'une collection que vous pensez avoir jeté en le supprimant de votre collection. => l'objet entier et tout ce qu'il fait référence resteront en mémoire jusqu'à la sortie de la page. => vous devez penser à une méthode de destruction complète pour votre classe d'objets ou faire confiance à un framework mvc par exemple.
De plus, n'hésitez pas à utiliser la partie Arborescence de conservation des outils de développement Chrome.
la source
Il suffit d'étendre d'autres réponses ...
Les gestionnaires d'événements délégués ne seront pas supprimés lors de la suppression de l'élément.
Maintenant, vérifiez:
la source
En ce qui concerne
jQuery
, les méthodes courantes suivantes supprimeront également d'autres constructions telles que les gestionnaires de données et d'événements:retirer()
vide()
html ()
la source
Oui, le garbage collector les supprimera également. Cela pourrait ne pas toujours être le cas avec les navigateurs hérités.
la source