Event Cache is a small script which can store the events you have set on a page and remove them on unload. This way it can prevent memory leakage. Please read DHTML leaks like a sieve by Joel Webber for more information. Also, here’s a quote Jim Ley, who explains:
The Internet Explorer web browser [...] has a fault in its garbage collection system that prevents it from garbage collecting ECMAScript and some host objects if those host objects form part of a “circular” reference. The host objects in question are any DOM Nodes (including the document object and its descendants) and ActiveX objects. If a circular reference is formed including one or more of them, then none of the objects involved will be freed until the browser is closed down, and the memory that they consume will be unavailable to the system until that happens.
So, how can we solve this? If we make sure no references are left when the page unloads, there won’t be a problem. In the comments of Joel Webber’s article Dylan Schiemann mentioned that Alex Russell of NetWindows had written a solution for this problem. So I dived into the NetWindows code to look for it.
It turns out that what the NetWindows code does is caching all events set for the affected browsers and detaching the events on unload. Based on this principle I wrote EventCache.
Please also read the follow-up article.
Usage
The idea is that you hook EventCache into your normal event code. You simply add the information you need to set the event to the EventCache using the add method.
EventCache has the following properties and methods:
listEvents-
An
arraywhose items are arrays which contain the information in the following order:node,sEventName,fHandler,bCapture. Seeaddfor more information. add(node, sEventName, fHandler, bCapture)-
Add new information to
listEvents.node- A reference to the node on which the event has been set.
sEventName-
The name of the event.
Please note: this name must not be prefixed with
on
for any browser but Internet Explorer. The actual event you use must be prefixed withon
. For example, if your event isonclick,sEventNamemust beclick. If you use a custom event you can’t usefoo, but you have to useonfoo. Of coursesEventNamemust befoo. fHandler- A reference to the
functionwhich handles the event. bCapture- A
booleanwhich determines whether the event is triggered in capture mode or not. Does not apply to Internet Explorer.
flush()- Remove all cached events.
Please note: You have to make sure that EventCache.flush is fired on unload!
Examples
I’ve made two testcases. One with memory leaking, and one which uses Event Cache. You can also try the Event Cache testcase with feedback
As you can see these examples don’t use browser detection to see if cleaning the references is really necessary. That’s something for your own implementation.
Other Methods
There are some other ways to solve this problem. One would be to never keep references at all, but closures are too handy to do this. Another solution is to iterate over all elements in a document and remove specific events. This is the solution that Aaron Boodman proposed.
The downside with this method though is that it only works for events which use the so-called DOM 0 event model: element.onclick = function(){};. If you use element.attachEvent() or element.addEventListener() you need to remember the specific values you used to set the event, which means you have to cache it.
Considerations
The cache keeps references to the element on which you’ve set an event and the event handler. This means that it consumes memory itself. It also takes time to remove the events on unload.
Download and Licensing
EventCache is released under the CC-GNU LGPL. You can download version 1.0.
And Finally
If you have any questions about this article or the code, please contact me.
