Wenn ich ein übergeordnetes Element mit untergeordneten Elementen habe, an die Ereignis-Listener gebunden sind, muss ich diese Ereignis-Listener entfernen, bevor ich das übergeordnete Element lösche? (dh parent.innerHTML = '';
) Könnte es zu Speicherlecks kommen, wenn Ereignis-Listener nicht von einem Element getrennt sind, wenn es aus dem DOM entfernt wird?
javascript
dom
memory-leaks
dom-events
Alle Arbeiter sind wesentlich
quelle
quelle
IE < 10
sie als veraltet gelten und von niemandem verwendet werden, der zu diesem Zeitpunkt andere Websites als Yahoo und AOL besucht. Jeder, der zu diesem Zeitpunkt unironisch den Internet Explorer verwendet, wird wahrscheinlich eher Opfer eines indischen Telefonbetrugs oder eines Virus, als Probleme mit Ereignishandlern, die die Krabbe eines Browsers verlangsamen.Nur um die Infos hier zu aktualisieren. Ich habe verschiedene Browser getestet, insbesondere auf Speicherverluste für zirkulär abhängige Ereignis-Listener bei iframe-Onload-Ereignissen.
Der verwendete Code (jsfiddle stört den Speichertest, verwenden Sie also Ihren eigenen Server, um dies zu testen):
<div> <label> <input id="eventListenerCheckbox" type="checkbox" /> Clear event listener when removing iframe </label> <div> <button id="startTestButton">Start Test</button> </div> </div> <div> <pre id="console"></pre> </div> <script> (function() { var consoleElement = document.getElementById('console'); window.log = function(text) { consoleElement.innerHTML = consoleElement.innerHTML + '<br>' + text; }; }()); (function() { function attachEvent(element, eventName, callback) { if (element.attachEvent) { element.attachEvent(eventName, callback); } else { element[eventName] = callback; } } function detachEvent(element, eventName, callback) { if (element.detachEvent) { element.detachEvent(eventName, callback); } else { element[eventName] = null; } } var eventListenerCheckbox = document.getElementById('eventListenerCheckbox'); var startTestButton = document.getElementById('startTestButton'); var iframe; var generatedOnLoadEvent; function createOnLoadFunction(iframe) { var obj = { increment: 0, hugeMemory: new Array(100000).join('0') + (new Date().getTime()), circularReference: iframe }; return function() { // window.log('iframe onload called'); obj.increment += 1; destroy(); }; } function create() { // window.log('create called'); iframe = document.createElement('iframe'); generatedOnLoadEvent = createOnLoadFunction(iframe); attachEvent(iframe, 'onload', generatedOnLoadEvent); document.body.appendChild(iframe); } function destroy() { // window.log('destroy called'); if (eventListenerCheckbox.checked) { detachEvent(iframe, 'onload', generatedOnLoadEvent) } document.body.removeChild(iframe); iframe = null; generatedOnLoadEvent = null; } function startTest() { var interval = setInterval(function() { create(); }, 100); setTimeout(function() { clearInterval(interval); window.log('test complete'); }, 10000); } attachEvent(startTestButton, 'onclick', startTest); }()); </script>
Wenn kein Speicherverlust vorliegt, erhöht sich der verwendete Speicher nach Ausführung der Tests um maximal 1000 KB. Wenn jedoch ein Speicherverlust auftritt, erhöht sich der Speicher um ca. 16.000 KB. Das Entfernen des Ereignis-Listeners führt immer zu einer geringeren Speichernutzung (keine Lecks).
Ergebnisse:
Schlussfolgerung: Bleeding Edge-Anwendungen können wahrscheinlich davonkommen, wenn Ereignis-Listener nicht entfernt werden. Aber ich würde es trotz des Ärgers immer noch als gute Praxis betrachten.
quelle