Now where’d I put that reference?

IE’s abysmal memory management is the bane of any professional JS developer’s life. Without rehashing all of the patterns, you can tell your app is running afoul of IE’s crappy reference counting when users report that it “feels slow” but that flushing the cache and/or restarting the browser “fixes” it. At this point you can either dig into the MSDN and Usenet articles on the topic and try to develop a workaround for your app, or you can use dojo.event.connect().

We didn’t cover it in the event system article,but Dojo transparently prevents leakage when you use dojo.event.connect(). Dojo isn’t the first system to do this, of course. The Signals and Slots system from netWindows baked in leakage prevention and others predate even it. As the problem has recently become better appreciated, other modern tools are starting to deal with leaks.

For those using Dojo, the solution to leakage is amazingly straightforward. In almost every case, you can just replace your node.onclick = function(){ ... }; statements with dojo.event.connect() equivalents and the leakage disappears. Under the covers, the node and the connected-to event handlers are placed in a “registry” for cleanup when the page starts to dissapear. A small map of property names is stored on the nodes so that the system never tries to strip more properties than necessary (which can be a serious performance problem).

The only exception to the transparency of this system is when DOM nodes are destroyed before the page unloaded. In these cases, DOM nodes may go out of scope and become “unreachable” by the event system for cleanup when the page unloads. To prevent leakage in these situations, Dojo provides dojo.event.browser.clean(nodeRef) to let you make sure that you’re “OK”. If you are going to remove nodes from a page, you can use this idiom to make sure that your app doesn’t leak:

dojo.event.browser.clean( parent.removeChild( child ) );

Of course, this leak prevention is also tied into the guts of the Dojo widget system. Event handlers in widget templates are automatically registered for cleaning and when a widget is destroyed, the system takes care to clean up after you.

While many developers will inevitably roll their own and spend painful weeks trying to manually track down leakage, users of Dojo may never have to know that it was a problem. Which is how it should be.

Next time: how dojo.io.bind() lets you upload files and beat memory leaks, all before lunch.

3 Comments

  1. Dan
    Posted December 23, 2005 at 1:30 am | Permalink

    Why don’t you just make that “remove node idiom” a standard dojo function (like dojo.event.brower.removeCleanly(node)). I’d never remember to use the idiom, but a function I could handle…

  2. Posted December 23, 2005 at 1:36 am | Permalink

    Good call. I’m not sure it should really live in dojo.event.browser, but perhaps in dojo.dom or dojo.html. I’ll post back when it’s in.

    Regards

  3. solrac
    Posted April 12, 2006 at 5:46 pm | Permalink

    We encountered memory leaks in IE with a project using dojo and initially looked at dojo as suspect. Upon reasearch it seems like Dojo actually takes measures to AVOID leaks if properly used. (i.e. always using dojo.event.connect())

    Dojo really needs some official documentation that lays all this kind of stuff out…

    Thanks!
    -Carlos-

One Trackback

  1. By planet::dojo » Dojo Gems for the New Year on December 31, 2005 at 3:53 pm

    […] How dojo.event.connect() prevents memory leaks […]