Movin’ on up, to the client side

I launched a new feature for DNZO last week: fast, JavaScript-based task sorting. Instead of forcing a new page load, tasks are sorted near-instantly on the client side. In order to enable bookmarking and the back button, I used the PrototypeXtensions.js library’s history manager — after a bit of hackery to get it working as I expected.

This move to JavaScript for sorting mirrors a common theme I’ve experienced in developing DNZO: I’ve slowly moved a lot of things over to the client side to increase responsiveness, minimize server-side requests and keep the requests that do need to happen light.

Original plan: JavaScript as frosting

When I started building DNZO, I initially designed the JavaScript side of things as sort of a frosting on top of the server side logic.

For example, clicking “edit” on a task fired an Ajax.Request to the edit link’s href (e.g. /t/1234), whose server-side counterpart supplied the markup for editing that task. It was really nice, because I had less state to manage and didn’t have to know anything about the structure of the tasks table. Similarly, script.aculo.us’s Ajax.Autocompleter initially loaded autocomplete suggestions from the server side by requesting something like /projects/?q=DN…, and the script just displayed the suggestions once it got them. The App Engine datastore did most of the work for me, and since the suggestions were updated whenever tasks were saved, I didn’t have to worry about suggestions becoming out of date.

The frosting technique provided three primary advantages:

  1. Less client-side logic. When you write your app this way, the client side is pretty dumb. My edit link just replaced something with an Ajax call and the autocompleter just asked somebody else for suggestions. Totally straightforward and less prone to cross-browser quirks.
  2. Cleaner initial markup. In the case of the edit button, I didn’t have to include each task’s inline-editing markup (e.g. input fields, submit button, etc.), so the initial page size was smaller. There were also fewer hidden elements sitting around and nothing output as JSON for client-side consumption — there was no need for it.
  3. Very DRY. Using Ajax.Autocompleter for autocomplete meant the JavaScript side of things knew nothing of how to generate suggestions or how to keep a list of things to suggest. Moving this all to the client side with InstantAutocompleter meant I had to duplicate some of that functionality: I had to both update the list of things to suggest on the client side and permanently store that list of suggestions on the server side.

Unfortunately, the typical workflow for a user (read: me) ended up looking like this:

  1. Try to do something (e.g. click “edit”, type in part of a project name, etc.).
  2. Wait for an ajaxy spinner to stop spinning. Tap foot during a brief pause until the display finally changes.
  3. Complete the action.

Hitting the “edit” link and then waiting about a second for the request to complete was frustrating. Waiting for a list of suggestions to come back from an Ajax call reduced its utility to a point where I just didn’t use the autocomplete at all. And, similarly, waiting for an entire page load just to reverse your sort order just sucked.

Revised plan: JavaScript provides core functionality

So, I have a new strategy: Make things happen instantly in your web app if you can, even if you have to repeat yourself in JavaScript and even if you have to work a little harder on the client side. Things need to happen immediately, or the app will feel slow.

I think the main issue is that I originally thought of DNZO as a web site rather than a web application. I didn’t realize that I valued the app’s responsiveness over its code zen factor — especially when the web app purports to help people get things, er, done-zo.

Comments on “Movin' on up, to the client side”

Joel on April 9th, 2009

Respond to this comment

“I didn't realize that I valued the app's responsiveness over its code zen factor” Other way around? Either way, great line.

Taylor on April 9th, 2009

Respond to this comment

That's the order I intended — I mean to say I'd rather sacrifice “code zen” (minimal, beautiful, etc. code) if it means the app will feel zippier.

Add a comment

Thanks for visiting! Looking for more? Check out the archives.