Si tengo un elemento padre con hijos que tienen oyentes de eventos vinculados a ellos, ¿debo eliminar esos oyentes de eventos antes de borrar el padre? (es decir, parent.innerHTML = '';
) ¿Podría haber pérdidas de memoria si los detectores de eventos no se desvinculan de un elemento si se elimina del DOM?
javascript
dom
memory-leaks
dom-events
Todos los trabajadores son esenciales
fuente
fuente
IE < 10
se puede considerar obsoleto y no utilizado por nadie que vaya a sitios que no sean Yahoo y AOL en este momento. Cualquiera que use IE de forma poco irónica en este punto es más probable que sea víctima de una estafa telefónica india o contraiga un virus que tener problemas con los controladores de eventos que ralentizan su navegador.Solo para actualizar la información aquí. He estado probando varios navegadores, específicamente para detectar fugas de memoria para detectores de eventos dependientes circularmente en eventos de carga de iframe.
El código utilizado (jsfiddle interfiere con las pruebas de memoria, así que use su propio servidor para probar esto):
<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>
Si no hay pérdida de memoria, la memoria utilizada aumentará alrededor de 1000 kb o menos después de que se ejecuten las pruebas. Sin embargo, si hay una pérdida de memoria, la memoria aumentará en aproximadamente 16.000 kb. Quitar primero el detector de eventos siempre da como resultado un menor uso de memoria (sin fugas).
Resultados:
Conclusión: las aplicaciones de Bleeding Edge probablemente puedan salirse con la suya sin eliminar los detectores de eventos. Pero aún lo considero una buena práctica, a pesar de la molestia.
fuente