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() {
obj.increment += 1;
destroy();
};
}
function create() {
iframe = document.createElement('iframe');
generatedOnLoadEvent = createOnLoadFunction(iframe);
attachEvent(iframe, 'onload', generatedOnLoadEvent);
document.body.appendChild(iframe);
}
function destroy() {
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:
- IE6 - Speicherverlust
- IE7 - Speicherverlust
- IE8 - kein Speicherverlust
- IE9 - Speicherverlust (???)
- IE10 - Speicherverlust (???)
- IE11 - kein Speicherverlust
- Kante (20) - kein Speicherverlust
- Chrome (50) - kein Speicherverlust
- Firefox (46) - schwer zu sagen, leckt nicht schlecht, also vielleicht nur ineffizienter Müllsammler? Endet ohne ersichtlichen Grund mit zusätzlichen 4 MB.
- Opera (36) - kein Speicherverlust
- Safari (9) - kein Speicherverlust
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.