요소를 제거하기 전에 이벤트 리스너를 제거해야합니까?
이벤트 리스너가 바인딩 된 자식이있는 부모 요소가있는 경우 부모를 지우기 전에 해당 이벤트 리스너를 제거해야합니까? (즉, parent.innerHTML = '';
) 이벤트 리스너가 DOM에서 제거 된 경우 요소에서 바인딩 해제되지 않으면 메모리 누수가 발생할 수 있습니까?
짧은 대답 : 예
긴 답변 : 대부분의 브라우저는이를 올바르게 처리하고 해당 처리기를 제거합니다. 이것을 엉망으로 만드는 일부 오래된 브라우저 (IE 6 및 7)가 있습니다. 예, 메모리 누수가있을 수 있습니다. 이것에 대해 걱정할 필요는 없지만해야합니다. 한 번 봐 가지고 이 문서를 .
여기에서 정보를 업데이트하기 만하면됩니다. 저는 특히 iframe onload 이벤트에서 순환 종속 이벤트 리스너에 대한 메모리 누수를 위해 다양한 브라우저를 테스트했습니다.
사용 된 코드 (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() {
// 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>
메모리 누수가 없으면 테스트가 실행 된 후 사용 된 메모리가 약 1000kb 이하로 증가합니다. 그러나 메모리 누수가 발생하면 메모리가 약 16,000kb 증가합니다. 이벤트 리스너를 먼저 제거하면 항상 메모리 사용량이 낮아집니다 (누수 없음).
결과 :
- IE6-메모리 누수
- IE7-메모리 누수
- IE8-메모리 누수 없음
- IE9-메모리 누수 (???)
- IE10-메모리 누수 (???)
- IE11-메모리 누수 없음
- Edge (20)-메모리 누수 없음
- Chrome (50)-메모리 누수 없음
- 파이어 폭스 (46)-말하기 어렵고, 유출이 심하지 않아서 비효율적 인 가비지 수집기일까요? 명백한 이유없이 추가 4MB로 완료됩니다.
- Opera (36) - no memory leak
- Safari (9) - no memory leak
Conclusion: Bleeding edge applications can probably get away with not removing event listeners. But I'd still consider it good practice, in spite of the annoyance.
'IT박스' 카테고리의 다른 글
Spinner가 텍스트를 줄 바꿈하지 않습니다. Android 버그입니까? (0) | 2020.11.21 |
---|---|
ScrollView 내에서 TableView의 스크롤을 자연스럽게 만드는 방법 (0) | 2020.11.21 |
“UseTaskFriendlySynchronizationContext”의 의미는 무엇입니까? (0) | 2020.11.21 |
두 조각 간의 기본 통신 (0) | 2020.11.20 |
html5 및 (canvas 또는 svg)를 사용하여 그리드를 그리는 방법 (0) | 2020.11.20 |