pagina funcion evento español eliminar ejecutar cargar javascript dom javascript-events memory-leaks

javascript - funcion - ¿Debo eliminar los detectores de eventos antes de eliminar los elementos?



funcion onload javascript (2)

Respuesta corta:

Respuesta larga: la mayoría de los navegadores manejan esto correctamente y eliminan esos manejadores ellos mismos. Hay algunos navegadores más antiguos (IE 6 y 7, si no recuerdo mal) que están estropeando esto. Sí, podría haber pérdidas de memoria. No deberías tener que preocuparte por esto, pero debes hacerlo. Eche un vistazo a este documento .

Si tengo un elemento primario con hijos que tienen receptores de eventos vinculados a ellos, ¿necesito eliminar esos detectores de eventos antes de borrar el padre? (es decir, parent.innerHTML = ''''; ) ¿Podría haber fugas de memoria si los detectores de eventos no están separados de un elemento si se eliminan del DOM?


Solo para actualizar la información aquí. He estado probando varios navegadores, específicamente para fugas de memoria para receptores de eventos dependientes circularmente en eventos de carga iframe.

El código utilizado (jsfiddle interfiere con las pruebas de memoria, por lo tanto, 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á en alrededor de 1000kb 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,000kb. La eliminación del detector de eventos primero siempre da como resultado un menor uso de memoria (sin pérdidas).

Resultados:

  • IE6 - pérdida de memoria
  • IE7 - pérdida de memoria
  • IE8: sin pérdida de memoria
  • IE9 - pérdida de memoria (???)
  • IE10 - pérdida de memoria (???)
  • IE11: sin pérdida de memoria
  • Edge (20) - sin pérdida de memoria
  • Chrome (50): sin pérdida de memoria
  • Firefox (46): difícil de decir, no se filtra mal, ¿entonces tal vez solo un recolector de basura ineficiente? Termina con 4MB extra sin razón aparente.
  • Opera (36) - sin pérdida de memoria
  • Safari (9): sin pérdida de memoria

Conclusión: las aplicaciones de borde sangrante probablemente salgan impunes al no eliminar los detectores de eventos. Pero aún así lo consideraría una buena práctica, a pesar de la molestia.