Wenn ein DOM-Element entfernt wird, werden seine Listener auch aus dem Speicher entfernt?
quelle
Wenn ein DOM-Element entfernt wird, werden seine Listener auch aus dem Speicher entfernt?
Einfaches JavaScript
Wenn ein entferntes DOM-Element referenzfrei ist (keine Verweise darauf), dann ja - das Element selbst wird vom Garbage Collector sowie allen damit verbundenen Event-Handlern / Listenern aufgenommen.
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.
Jedoch; Wenn es noch Referenzen gibt, die auf dieses Element verweisen, bleiben das Element und seine Ereignis-Listener im Speicher.
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
Es wäre fair anzunehmen, dass die relevanten Methoden in jQuery (wie z. B. remove()
) genauso funktionieren würden (wenn remove()
man bedenkt , removeChild()
dass sie beispielsweise mit geschrieben wurden).
Dies ist jedoch nicht wahr ; Die jQuery-Bibliothek verfügt tatsächlich über eine interne Methode (die nicht dokumentiert ist und theoretisch jederzeit geändert werden kann) mit dem Namen cleanData()
(so sieht diese Methode aus ), die beim Entfernen aus dem DOM automatisch alle Daten / Ereignisse bereinigt, die einem Element zugeordnet sind (sei dies über. remove()
, empty()
, html("")
usw.).
Ältere Browser - insbesondere ältere Versionen von IE - haben bekanntermaßen Probleme mit Speicherverlusten, da Ereignis-Listener Verweise auf die Elemente behalten, an die sie angehängt wurden.
Wenn Sie eine ausführlichere Erläuterung der Ursachen, Muster und Lösungen zur Behebung älterer Speicherlecks in der IE-Version wünschen, empfehlen wir Ihnen, diesen MSDN-Artikel zum Verständnis und Lösen von Internet Explorer-Leckmustern zu lesen .
Einige weitere relevante Artikel:
Das manuelle Entfernen der Listener selbst wäre in diesem Fall wahrscheinlich eine gute Angewohnheit (nur wenn der Speicher für Ihre Anwendung so wichtig ist und Sie tatsächlich auf solche Browser abzielen).
remove
Methode. Meistens wird das DOM nur vollständig gelöscht. (wie Turbolinks oder so). Ich frage mich, wie das Gedächtnis beeinflusst wird, wenn ichdocument.body.innerHTML = ''
...zu jQuery:
Referenz: http://api.jquery.com/remove/
jQuery v1.8.2
.remove()
Quellcode:anscheinend verwendet jQuery
node.removeChild()
Demnach: 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.
Das heißt, Ereignis-Listener werden möglicherweise entfernt, sind jedoch
node
noch im Speicher vorhanden.quelle
removeChild
Handlern nicht möglich wäre. Beide geben Ihnen auch eine Referenz zurück, die Sie behalten können, um letztere wieder anzubringen (in diesem Fall bleibt sie offensichtlich im Speicher) oder wegzuwerfen (in diesem Fall wird sie schließlich von GC aufgenommen und entfernt).Zögern Sie nicht, Heap zu beobachten, um Speicherlecks in Ereignishandlern zu sehen, die einen Verweis auf das Element mit einem Abschluss und das Element, das einen Verweis auf den Ereignishandler enthält.
Garbage Collector mag keine Zirkelverweise.
Üblicher Speicherverlustfall: Geben Sie zu, dass ein Objekt einen Verweis auf ein Element hat. Dieses Element hat einen Verweis auf den Handler. Und der Handler hat einen Verweis auf das Objekt. Das Objekt hat Verweise auf viele andere Objekte. Dieses Objekt war Teil einer Sammlung, von der Sie glauben, dass Sie sie weggeworfen haben, indem Sie sie aus Ihrer Sammlung entfernt haben. => Das gesamte Objekt und alles, worauf es verweist, bleibt bis zum Verlassen der Seite im Speicher. => Sie müssen über eine vollständige Kill-Methode für Ihre Objektklasse nachdenken oder beispielsweise einem MVC-Framework vertrauen.
Zögern Sie nicht, den Retention Tree-Teil der Chrome-Entwicklungstools zu verwenden.
quelle
Nur andere Antworten erweitern ...
Handler für delegierte Ereignisse werden beim Entfernen von Elementen nicht entfernt.
Überprüfe jetzt:
quelle
Bezüglich
jQuery
die folgenden gängigen Methoden werden auch andere Konstrukte wie Daten- und Ereignishandler entfernt:entfernen()
leeren()
html ()
quelle
Ja, der Garbage Collector entfernt sie ebenfalls. Dies kann jedoch bei älteren Browsern nicht immer der Fall sein.
quelle