Archive for the ‘AJAX’ Category

Improving AJAX performance of large tables of results…

November 6, 2007

I’ve been writing an AJAX site. I’ve got listings of results (40 per page) that I dynamically pull in from the server and allow the user to index through. Everything worked beautifully in firefox (rendered the new recordset in the page in less than 500ms). IE 6 however CHOKED bigtime – it took around 3-4 seconds to render the first “page” of results. And as each successive page of results was rendered (replacing the previous one) it progressively slowed, to the point that after the 4th page, it was taking 10+ seconds to render. I was just removing and dynamically adding rows to a table through the DOM.

First thing I found was this. That helped some. The next problem I looked into was using the prototype js libraries .each iterator. It’s really handy, but IE 6 performs very badly with it. So I replaced all of my loops over lists that could be long with standard for loops.

The next problem I found was that I was extending all of the elements I was using with the prototype js library to set styles and classes on them, and observing events. (Each entry in the recordset has several onclick events to deal with labels, etc). It turns out that IE majorly chokes on this. One of IE 6’s big problems is garbage collecting events. Prototype has done some work to help it with this. On page unload, they’ll automatically remove all event handlers (otherwise they permanently leak). The problem with my site was that I’m creating a bunch of events, and my page never unloads because I’m dynamically changing the content. So these event handlers just kept piling up. I can’t just call the prototype Event.unloadCache because I have other events on the page I want to keep – I’m just changing the main content in a table.

To work around this I ended up creating my own analogies to several of the prototype event functions. The Event.observe equivalent takes an extra (optional) parameter which specifies the name of an event group. Rather than just keeping a list of all events registered, I categorize them by this event group name so I can call the unloadCache equivalent method with this and ONLY unload the events from a given group. If no event group is specified to the unloadCache method, I remove all events (for instance, on the page unload event).

With these changes I was able to get get IE 6 consistently rendering the content in the page in around 500ms. Haven’t had a chance to note the performance numbers in IE 7 yet.

Also of interest if you’re looking into javascript performance is this simple javascript performance instrumentation helper. Nothing fancy, just a quick way to time various aspects of your app crossbrowser.