Просто чтобы обновить информацию здесь. Я тестировал различные браузеры, в частности, на предмет утечек памяти для циклически зависимых прослушивателей событий при событиях загрузки iframe.
Используемый код (jsfiddle мешает тестированию памяти, поэтому используйте свой собственный сервер для проверки):
<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>
Если утечки памяти нет, объем используемой памяти увеличится примерно на 1000 КБ или меньше после запуска тестов. Однако при утечке памяти объем памяти увеличится примерно на 16 000 КБ. Удаление сначала прослушивателя событий всегда приводит к меньшему использованию памяти (без утечек).
Полученные результаты:
- IE6 - утечка памяти
- IE7 - утечка памяти
- IE8 - без утечки памяти
- IE9 - утечка памяти (???)
- IE10 - утечка памяти (???)
- IE11 - нет утечки памяти
- Edge (20) - без утечки памяти
- Chrome (50) - без утечки памяти
- Firefox (46) - сложно сказать, утечки нет, может, просто неэффективный сборщик мусора? Заканчивается с дополнительными 4 МБ без видимой причины.
- Opera (36) - нет утечки памяти
- Safari (9) - без утечки памяти
Вывод: передовые приложения, вероятно, могут обойтись без удаления прослушивателей событий. Но я все равно считаю это хорошей практикой, несмотря на раздражение.