The Year of AJAX, Take Four: Part I

Unless you’ve been living in Plato’s cave for the last four years, trying to learn about web technology from shadows cast by someone’s monitor, you’ve at least heard of AJAX. It’s the wave of the (very near) future for web applications, one of the fundamental enabling technologies for “Web 2.0.” And, of course, this is the Year of AJAX, just like 2007 was. And 2006, 2005, and 2004.

It’s not that AJAX never really came into being. The technology has certainly been there since at least 2004. And plenty of web sites out there are using it. But it hasn’t become nearly as ubiquitous on the web as people keep constantly predicting. I think part of the reason is that developing AJAX applications from the ground up is not exactly easy, and is very time consuming, and there haven’t been a whole bunch of extensive, declaratively usable AJAX toolkits that integrate well with standard enterprise application technologies like JavaServer Faces.

Is that about to change? Oracle is now in Technical Preview 4 of Oracle JDeveloper 11g, and a production release is hoped for by the end of the year. JDeveloper 11g includes ADF Faces 11g, which itself includes the ADF Faces Rich Client components. ADF Rich Client (ADF RC) components, according to Oracle, “[extend] the Apache Trinidad component framework to provide a rich set of AJAX-enabled JSF components that radically simplifies rich internet application development.”

How good are the ADF Faces Rich Client components? They’re really very, very good. Oracle has come out with the technology to create applications that have a very desktop-y feel, with a lot of the whiz-bang stuff that often gets talked about in connection with AJAX, and it’s a big step up from ADF Faces 10g. You’ve got your lazy-loading tables, your non-lazy-loading trees (very nice for <100-node trees; certainly much better than invoking PPR every time you open or close a node), your drag-and-drop, your fancy popups, your keep-alive poll, your data visualization components, and on and on. You can do things on rollover, selection, click or right-click, scrolling, etc., etc. I’m not going to be able to do the components justice here, so check them out. Really.

I want to stress how wonderful I think these components are (and I do), because I’m about to make a criticism that I imagine the developers would find shocking: They’re not AJAX, at least not out-of-the-box. Which means this isn’t the declarative framework that will finally bring about the Year of AJAX.

In case you’re not familiar with exactly what AJAX means, it’s an acronym (of course) for Asynchronous Javascript and XML. The idea is that the client, running in the browser, uses Javascript to send XML messages to the server, receive the server’s XML response, and update the visual form appropriately (as opposed to submitting an entire form and asking the server to resend a complete page). This communication is asynchonous, meaning that that, after the Javascript has sent the XML message to the server, it does not block other processes (such as user interaction with the form) while waiting for the server’s response.

There is absolutely no question that ADF Faces Rich Client makes excellent use of Javascript and XML. Unlike ADF Faces 10g, where only one event per component (such as blurring a text field with a changed value, selecting an item from a dropdown list, or selecting a radio button) could trigger only one sort of communication (a partial page refresh submission of the form), the client-side Rich Client components can send very efficient XML messages to the server based on almost any Javascript event, and the server-side components can send very efficient XML messages in response.

But what these messages are not, by and large, are asynchronous. They still block user input, albeit for just a small amount of time.

Take, for example, the lazy-loading table component. A table, in ADF Faces Rich Client, can sit inside a scroll pane. When the table first loads, if content delivery is set to “lazy” (the default), ADF will query the first range of rows (the range size is configurable on the data binding) and renders the table with just those rows showing. If the user scrolls down far enough that out-of-range rows are required, the browser sends a (non-asynchronous) message to the server, where ADF queries enough ranges’ worth to cover the rows that are displayed. The values for those rows are sent to the browser in an XML message, and the browser adds appropriate <tr>s to the <table> using Javascript.

Between the time the user scrolls and the time the table is ready, user input is blocked (because the call isn’t asynchronous) and the UI puts up a little “Retrieving Data…” popup. This isn’t very disruptive. For me, it’s under a second when going against Oracle’s on-line demo, even if I scroll down hundreds of rows at once. On the other hand, I’m connecting over a high-speed cable connection, and I live about 3 miles from Oracle, so it’s not like I’m having much trouble with either bandwidth or latency. My guess is it’s pretty good from anywhere…but could it be made better using asynchronous calls?

Yes, it could. Here’s how I’d love to see a lazy-loading table function in 12g :

When the user loads the page, as before, the first range of rows should be downloaded. But before the user even touches the table, a timer starts, so that every x seconds, where x can be configured based on how many hits your server can comfortably handle, the next range is requested, queried, and downloaded asynchronously. If the user catches up to the asynchronous downloads by rapid scrolling, then the framework could of course fall back on its current behavior–do a single synchronous load to catch up. But the chance of this happening would be much reduced, without initial page download being slowed at all.

Similarly, right now you have a choice about validation. You can implement it client-side in Javascript (redundantly, since implementing validation on the client only is insecure), which requires you to get all data that might possibly be needed for validation from the server at load (this might slow down loading considerably–think of LOV validation with lots of rows). You can wait until the entire form is filled out and submitted, which is inferior in terms of interactivity and modern feel. Or you can synchronously request validation and partial page refresh after every single field that requires it. That last might sound great, but trust me, it get’s extremely annoying when you have to wait even half a second whenever switching fields in a large form.

Or it could be done asynchronously. Every time you switch fields, my hypothetical 12g text input component would fire an asynchronous request for validation. The user can continue filling out the form in the mean time, and as soon as a problem is detected with the original field, the browser is notified and flags the offending field appropriately.

Now, this sort of asynchronous communication isn’t appropriate for everything. Consider dependent dropdowns. I once developed a simple web store for a client. In this webstore were, among other things, various items of clothing. A clothing item had a size, a color, and (sometimes) a style. As is typical, not all colors were available in all sizes, and not all styles were available in all size/color combinations. Unsurprisingly, I implemented this as a set of three dependent dropdowns–the color dropdown wasn’t populated until you selected a size, and the style dropdown wasn’t populated until you selected a color.

Doing this asynchronously wouldn’t have been a great idea. You really don’t want the user to continue with the form (by selecting a color) before the available colors were determined. You need to do this either via synchronous PPR (which I did then) or by initially inlining all possible size/color/style combinations (the average product had under 50) and showing/hiding them using client-side calculations (which I would probably do if I had it to do over again).

So some Javascript-and-XML requests need to be synchronous…but not all of them. Truly leveraging the power of AJAX would involve making much more use of asynchronous requests. I’m afraid that 2008 is once again not the year of AJAX.

Oh well. Maybe 2009.

In next week’s entry, I’ll talk about some options to tide you over.

Leave a Reply

Your email address will not be published. Required fields are marked *