Graceful Degradation with Prototype, Scriptaculous and Ruby on Rails - Part 1: What's The Beef?

—Friday, November 11 2005

After a respectable exchange with Jeremy Keith and Ryan Cambell about an earlier article I published; I decided to take a deeper look at the problem domain of degredation. Jeremy suggest that degradation doesn’t involve extra time, the keyword here being extra. He suggest it should be looked at more of as a requirement in the planning phase rather than something we debate as an optional perk.

I can give a first hand account–if you choose to make your application degrade gracefully, you absolutely should establish this in the planning phase as a requirement and not something you might do down the road if time and capital permit it. If you try to go back and do tack-on degradation you’ll find yourself in a world of hurt depending on the complexity of your application. I did things the hard way and took and existing application and tried to degrade it. It was never in the plans to degrade and degradation is still not widely adopted, so there aren’t that many resources or real world examples that go beyond the scale of a contact form or small unit of functionality.

Application scale functionality

Visual effects

Drag and Drop, expanding and collapsing elements, fading in and out, changing colors, all of these and more are things we’ll either have to provide an alternative method for or determine whether or not we’ll need them in our zero-javascript environment.

Javascript visual effects have sadly been mixed and mangled with the term Ajax, but they have absolutely nothing to do with Ajax; They are merely a means of modifying the physical characteristics of a DOM element, but we’ll save that for another blog.

Visual effects through Javascript have become popular with the rise of Ajax. Before Ajax took a foothold in the world of application development users have become accustom to the page refresh in order to show them something just happened. With Ajax we loose the page refresh so we need to provide some mechanism to show something just happened–This has become the area where tasteful visual effects shine.

If a user doesn’t have Javascript enabled, we’ll be able to safely exclude some effects that serve as visual cues to the user because we now have our page refresh back.

Ajax

Ajax the technology precedes the term itself by years, but the now famous article entitled “Ajax: A New Approach to Web Applications” published by Jesse James Garrett from Adaptive Path thrust it into the limelight. Currently the market for Ajax based applications is exploding and everyone is rushing to the front lines in order to claim there stake.

With Ajax we no longer have to deal with the start-stop-start-stop nature of interaction on the Web as Jesse James put it. All of the work is done behind the scenes asynchronously in most cases.

When using Ajax we do a lot of client side DOM manipulation: adding a new item to a to-do list, deleting a row from a table, and it can go as far as loading a whole new interface for the user to interact with. All of this will need a fallback of some kind and we’ll surely get into that later.

What was once second nature

You might be tempted to do something like this in your code to provide a container for error messages:

<div style="display:none;" id="errors"></div>

In it’s current state, there is no way this can degrade. You would normally use Javascript to make this element appear if any errors surfaced during a request but if you plan to make it appear with Javascript you also have to hide it with Javascript or by using your server-side language of choice.

Looking at a slightly sticker example where problems will arise:

<tbody>
  <tr>
    <td>Justin</td>
    <td>500 cool points</td>
  </tr>
  <tr class="hide" onclick="Element.show(this)">
    <td colspan="2">
      <a href="/edit/2">Edit</a>
      <a href="/delete/2">Delete</a>
   </td>
 </tr>
</tbody>

Never-mind the forbidden onclick, it’s the least of our problems at the moment. Imagine for a moment that you were degrading your application and on first request you found all elements whose class name was equal to hide and set those elements display to none.

Now we’ve sent an Ajax request that loaded the fragment of html above into our table listing of which user had the most cool points. Have you spotted the problem yet? The tr element with class="hide" will not be hidden because we took care of all of that once the page first initialized. In good faith we’ve tried to degrade our application, but it has quickly just bitten us in the ass. We’ll now need to implement a solution for the solution. It’s all quiet possible and I’ll discuss it in part two of this 3 part series coming shortly.

UPDATE: Part 2 has been published