If a DOM Element is removed, are its listeners removed from memory too?
相关问题
- Is there a limit to how many levels you can nest i
- How to toggle on Order in ReactJS
- How to fix IE ClearType + jQuery opacity problem i
- void before promise syntax
- jQuery add and remove delay
Don't hesitate to watch heap to see memory leaks in event handlers keeping a reference to the element with a closure and the element keeping a reference to the event handler.
Garbage collector do not like circular references.
Usual memory leak case: admit an object has a ref to an element. That element has a ref to the handler. And the handler has a ref to the object. The object has refs to a lot of other objects. This object was part of a collection you think you have thrown away by unreferencing it from your collection. => the whole object and all it refers will remain in memory till page exit. => you have to think about a complete killing method for your object class or trust a mvc framework for example.
Moreover, don't hesitate to use the Retaining tree part of Chrome dev tools.
Regarding
jQuery
, the following common methods will also remove other constructs such as data and event handlers:remove()
empty()
html()
regarding jQuery:
Reference: http://api.jquery.com/remove/
jQuery v1.8.2
.remove()
source code:apparently jQuery uses
node.removeChild()
According to this : https://developer.mozilla.org/en-US/docs/DOM/Node.removeChild ,
The removed child node still exists in memory, but is no longer part of the DOM. You may reuse the removed node later in your code, via the oldChild object reference.
ie event listeners might get removed, but
node
still exists in memory.Modern browsers
Plain JavaScript
If a DOM element which is removed is reference-free (no references pointing to it) then yes - the element itself is picked up by the garbage collector as well as any event handlers/listeners associated with it.
However; if there are references that still point to said element, the element and its event listeners are retained in memory.
jQuery
It would be fair to assume that the relevant methods in jQuery (such as
remove()
) would function in the exact same way (consideringremove()
was written usingremoveChild()
for example).However, this isn't true; the jQuery library actually has an internal method (which is undocumented and in theory could be changed at any time) called
cleanData()
(here is what this method looks like) which automatically cleans up all the data/events associated with an element upon removal from the DOM (be this via.remove()
,empty()
,html("")
etc).Older browsers
Older browsers - specifically older versions of IE - are known to have memory leak issues due to event listeners keeping hold of references to the elements they were attached to.
If you want a more in-depth explanation of the causes, patterns and solutions used to fix legacy IE version memory leaks, I fully recommend you read this MSDN article on Understanding and Solving Internet Explorer Leak Patterns.
A few more articles relevant to this:
Manually removing the listeners yourself would probably be a good habit to get into in this case (only if the memory is that vital to your application and you are actually targeting such browsers).
Just extending other answers...
Delegated events handlers will not be removed upon element removal.
Now check:
Yes, the garbage collector will remove them as well. Might not always be the case with legacy browsers though.