Chỉ cần cập nhật thông tin ở đây. Tôi đã thử nghiệm các trình duyệt khác nhau, đặc biệt để kiểm tra rò rỉ bộ nhớ cho các trình xử lý sự kiện phụ thuộc một cách vòng tròn vào các sự kiện onload iframe.
Mã được sử dụng (jsfiddle can thiệp vào việc kiểm tra bộ nhớ, vì vậy hãy sử dụng máy chủ của riêng bạn để kiểm tra điều này):
<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>
Nếu không có rò rỉ bộ nhớ, bộ nhớ đã sử dụng sẽ tăng khoảng 1000kb hoặc ít hơn sau khi chạy thử nghiệm. Tuy nhiên, nếu bị rò rỉ bộ nhớ thì bộ nhớ sẽ tăng thêm khoảng 16.000kb. Việc loại bỏ trình nghe sự kiện trước tiên luôn dẫn đến việc sử dụng bộ nhớ thấp hơn (không bị rò rỉ).
Các kết quả:
- IE6 - rò rỉ bộ nhớ
- IE7 - rò rỉ bộ nhớ
- IE8 - không bị rò rỉ bộ nhớ
- IE9 - rò rỉ bộ nhớ (???)
- IE10 - rò rỉ bộ nhớ (???)
- IE11 - không bị rò rỉ bộ nhớ
- Cạnh (20) - không bị rò rỉ bộ nhớ
- Chrome (50) - không bị rò rỉ bộ nhớ
- Firefox (46) - khó nói, không bị rò rỉ nghiêm trọng, vì vậy có thể chỉ là trình thu gom rác kém hiệu quả? Kết thúc với thêm 4MB mà không có lý do rõ ràng.
- Opera (36) - không bị rò rỉ bộ nhớ
- Safari (9) - không bị rò rỉ bộ nhớ
Kết luận: Các ứng dụng cạnh chảy máu có thể thoát khỏi việc không xóa trình nghe sự kiện. Nhưng tôi vẫn coi đó là một thực hành tốt, mặc dù có chút khó chịu.