When AJAX is too slow

Back in the day, web pages were just web pages. What you see is (more or less) what you got. These days, we have web applications where there’s a lot of back-and-forth communication between the web browser and the web server. In essence, where you used to load a new page to get more data, your web browser just updates a portion of the page you’re already on. The new model is called AJAX.

That works great when you’re going to be interacting with a web application for a long time. But if you want to load the page quickly and then jump to a different page, AJAX can be a bad idea. I’ve got one of those situations at work right now. It’s a to-do list, where people choose a task to work on. Someone will eventually need to do all the tasks, but when the list is big they’ll either just click on the first one (to hurry) or look more carefully and do triage.

My first attempt was a single web page with all the tasks in an HTML table. When the table is moderately large (over 30 tasks), it took over a second to load. After a day of optimization, I got that down to 0.6 to 0.7 seconds. Not the 0.1 seconds that Google recommends, but reasonable. If it takes more than a second the user’s mind will wander while waiting for it.

Then I AJAXified it. Converted the simple HTML table to a YUI Datatable. My 0.6 seconds shot up to 1.7 seconds. Why? Instead of loading one web page and rendering it, it now (1) loads the web page, (2) loads the JavaScript program that displays the datatable, (3) waits for the web page to finish rendering before running that program, (4) the program calls the web server to get the column descriptions, and then (4) the program calls the web server to get the data. The column data (which takes 0.2 seconds to generate) is being generated in triplicate. The to-do tasks themselves take half a second (0.13 seconds each), but–and this is the real killer– we don’t even start on that until everything else is done.

So how do we make this quicker? We need to move as much as possible back into the original page: un-AJAXify it. In my case, that’s not easy. Behind the scenes, the web page is constructed with XHTML and then converted into HTML before being sent to the web browser. I’ve got a lot of helper code that assumes we’re doing XHTML, so that’s not negotiable. XHTML is a lot like HTML, except that we can’t just dump a block of JavaScript into it. Nor can we send it as XHTML and pretend it’s HTML. The web browser, upon seeing that, assumes we don’t know what we’re doing and tries to “fix” it in ways that break things. So to totally un-AJAXify it, I’ll need to go back to writing a simple (X)HTML table, and then write some JavaScript to convert that into the YUI DataTable.

Another option is to take the to-do list payload and treat it as a JavaScript script, so it gets loaded simultaneously with the other scripts and images on the page. This is what I call Poor-Man’s AJAX, because I used that trick back in the days when only Internet Explorer supported AJAX. It’s not quite as fast in my case as having the data in the page, but it should still be fairly fast, and it’s easier to program.

The moral of the story? Sometimes the new, fast way of doing things can slow you down, so it’s good to have some old-fashioned tricks up your sleeves. Though, this being computers, old-fashioned means circa 2004 or so. (When you’re really in trouble, that’s when you reach back to your circa-1980 performance tricks. But that’s a story for another day.)