Exploring Ajax Runtime Offerings

by Gary Horen
12/06/2006

Abstract

The browser technologies that led to the current Ajax wave have been available since early 1999. But the programming interfaces they originally presented were very low-level and painful to work with, and the browser and JavaScript tricks that comprised Ajax could often demand more of the client machine than it had to give. With the additional memory, processor, and network bandwidth capacities that have become ubiquitous on the client machine in the last few years, Ajax has become a realistic way to develop rich user interfaces for Web applications. One effect of this is that a host of Ajax runtime frameworks has popped up that tries to present the developer with a more workable application programming model.

This article attempts to sort through these frameworks and map some of the characteristics by which they can be compared. The hope is that the reader will come away with some tools to use for breaking down the collection of Ajax offerings in ways that make it easier to understand distinctions between them, narrowing down the subset that needs to be looked at, and making better-informed choices.

Disclaimer: This article is focused on the Java EE world. Lots of interesting things can be said about other technologies from other genres, like .NET and Ruby, but these are beyond the scope of this article.

Introduction

Ajax is an acronym that stands for Asynchronous JavaScript And XML. It's one possible technology that you can use to create a type of Web application that the press has come to call a rich Internet application (RIA). RIAs are "rich," in the first place, because they appear to behave more like desktop applications than traditional page-refreshing Web applications. For example, controls on the page are interconnected in a fine-grained way (changing a value in a listbox may result in another control on the page being enabled or disabled, or disappearing altogether). Ajax enables many other visual effects that have not been possible in traditional Web applications. You can see a small subset of them here:

Another equally important characteristic of a rich application is that the UI communicates with its data source (that is, with the server), without requiring the page refresh associated with a traditional Web application.

Using Ajax is not the only way to create a rich Web application. You can use Adobe's Flash plug-in, which is found in a very large subset of the browsers out in the world today. Another alternative is one of the browser-specific rich UI technologies like XAML for Internet Explorer, and XUL for Mozilla. The principal advantage of Ajax is that it really is the zero-footprint solution: It works across the vast majority of modern browsers, and it uses only what it finds on the client. No additional plug-ins on the client machine need to be kept in synch with the server side of an Ajax application.

This is not to say that there are no differences in Ajax technology implementations among browsers. The native browser APIs are not standardized, at either the syntactic or behavioral levels. The reason that Ajax applications generally don't have to worry about implementation differences among browsers is that the Ajax runtime frameworks do the worrying for them.

At the lowest level, without a framework, raw Ajax programming requires:

  • An asynchronous pipe to the server (that is, an API to communicate with the server that does not freeze the UI and refresh the Web page). This is the XMLHttpRequest object.
  • A language to construct and parse messages, and to manipulate the browser DOM. This is JavaScript.
  • A markup language to create an initial page layout (not always but usually). This is DHTML.
  • A data representation for the messages that flow between the Web page and the server. This is nominally XML, but since the XMLHttpRequest object does not examine the dataflow, it can be any representation that the client and server both agree upon. JSON (JavaScript Object Notation) is a popular alternative.

Development using raw Ajax is difficult because of inter-browser variability, and also because of the relative immaturity and the browser-dependent state of the art of the available development tools that work at this level. So, a large number of Ajax runtime frameworks have sprouted up. This article tries to provide an overview of the space, and a way to break the frameworks down and understand their similarities and differences.

Navigating the Ajax Framework Space

Ajax runtime frameworks come in many forms and have a wide variety of goals. Some simply intend to paper over the differences in browser interfaces, and provide a common API for sending and receiving server messages. Others are mostly concerned with UI widgetry and/or special visual effects. Other frameworks try to address both concerns. One tool that I've found useful for making comparisons among frameworks is to view them along a set of different axes, as shown in Figure 1. You could come up with quite a large number of these, but this article will focus on just the four that appear in the figure below. I'll discuss them one at a time. Keep in mind that the distinctions I make are shades of gray; they are general rules for which you will always be able to find exceptions.


Figure 1. Axes of Ajax

Open source vs. commercial

Open-source versus commercial is a distinction that anyone who lives in the Java EE world is quite familiar with already. Commercial frameworks are often more mature, because a commercial offering is usually part of the vendor company's mission and commands the owning organization's full attention. The vendor usually has a stronger commitment to backward compatibility from release to release. These products are more often designed to be comprehensive end-to-end solutions. They characteristically have better documentation and commercial-quality support.

Open-source frameworks are often more uneven: They can be excellent in areas in which the community of developers focuses its efforts, and weaker in areas that receive less focus. The attention paid to a feature is often driven by the needs of its contributing developer. Support and documentation can be causes for concern, and if you decide to adopt an open-source framework for your project, you need to make sure that the license under which it is offered is suitable for your planned use for it. If your application is designed to be shipped to customers, rather than be used strictly within your own organization, then you must make sure that you have the right to redistribute any framework-owned artifacts that your application requires.

On the other hand, since an open-source framework is usually designed to invite contributions from the community, it's often easier to add functionality that you may find missing to one of these than to add it to a commercial product. Furthermore, if you choose an open-source framework with an active community behind it, support can be excellent.

Comprehensive framework vs. individual components

Ajax runtime component offerings run the gamut from scraps of sample code that you find on the Web and that you can cut and paste into your own application, to comprehensive frameworks. Just above the level of code scraps are individual JavaScript components that present an API for a specific purpose. Some of these represent UI widgets that will appear on a Web page, like the Dojo Button, and others are for solving lower-level, plumbing-related issues like communicating with the server or manipulating the browser DOM (for example the Prototype APIs).

A comprehensive framework is a collection of these encapsulated objects that want to be a complete solution for an Ajax development project. Many of these assume that they "own" the Web page on which they run with regard to Ajax—that is, they often don't easily accommodate the notion of sharing the page with components from outside sources.

Making a choice along this axis is often related to the age of an application: A new one generally has an easier time dealing with the assumptions made a by a comprehensive package. To make incremental improvements to an existing Web application, it can often, although not always, be easier to integrate code scraps or objects. Scraps and individual components can require more programming, because they operate at a lower level. Comprehensive frameworks make assumptions that make them harder to integrate with each other, and are harder to use in a portal (because sometimes their assumptions conflict with ones made by the portal container).

Declarative vs. procedural

The declarative versus procedural distinction has to do with the programming model that the framework offers for authoring Web pages. Declarative ones want to provide a language in which the developer describes the layout of the UI on the page, and the relationships between them, so that the framework knows how to handle events that pass between UI widgets just from the description provided by the application developer. Procedural frameworks offer programming language APIs, and the programmer provides procedural code that handles UI events.

In Example 1 below, you can see the beginning of the declarative layout of a data table done with the ICESoft framework. The column shown is both a display for dynamic data and a command link; data bindings for both retrieving the data and passing the command to the server refer to JSF backing beans, and are specified in JSF expression language.

<ice:datatable>     

  <ice:column>

    <ice:commandLink actionListener="#{catalog.selectBook}">

      <ice:outputText value="#{book.title}" />

    </ice:commandLink>

  </ice:column>

  ...

Example 1. Declarative layout and event handling: ICEFaces

In Example 2 I use Dojo, a more procedural framework, to handle a button-pressed event in JavaScript, and to specify another JavaScript function, onServerResponse(), that will be called when data I request from the server arrives.

<script>

  function helloPressed() 

    {

      dojo.io.bind({

        url: 'response.txt',

        handler: onServerResponse

    });}

    ...

</script>

    

<button dojoType="Button2" widgetId="helloButton">

  Hello World!

</button>

Example 2. Procedural event handling: Dojo

Client-centric vs. server-centric

The client-centric versus server-centric distinction also is about the programming model, and is one of the most interesting ones. Early runtime frameworks were almost all focused on the client side: The Ajax part of a Web application executed in the browser, and communicated with server-side components that were independent of the Ajax framework. Recently, some frameworks have begun to offer an application programming model that uses the server-side language (for purposes of this discussion, Java), and, to varying degrees, blurs the apparent distinction between the server and browser environments.

If you look at the diagrams in Figure 2 below, you can see that in the server-centric model, the application programmer develops the entire application in what appears to the programmer to be server-side code. Of course, DHTML and JavaScript are involved when the application runs, but the framework does not expose these to the programmer. The framework provides both a server-side and client-side Ajax engine. The server-side engine generates HTML and JavaScript that is served into the browser along with a client-side engine, which provides APIs used by the generated code to manipulate the browser DOM, receive events, and push them back to the server-side engine, which communicates events back to the application.

Often, a server-centric framework will hold a representation of the widget DOM on both the server and the browser sides of the connection, and keep them in synch by sending deltas back and forth across the connection. Of course, this costs something in terms of server-side memory, but it can make it much easier to persist and restore the state of an Ajax session when the user disappears and then comes back sometime later and wants to resume work where it was left off.

A client-side framework, on the other hand, expects the application programmer to write both the server side of the application and the part that will run in the browser. The client-side code is served into the browser along with the Ajax engine, which performs the same intercession functions between the DOM and the application code that it does in the server-centric model. The application code initiates requests to the server through calls to engine APIs.


Figure 2. Server-centric vs. client-centric framework architecture

Figure 3 breaks this axis down further. The differences between the two client-side columns of the table are mostly about the level at which the framework expects programming to be done. The right-most entries are essentially JavaScript libraries, which are usually more concerned with plumbing than UI. UI layout using these can be expressed in either JavaScript code or standard HTML. In the next column to the left are higher-level frameworks that actually include an Ajax rendering engine. These expect the user to express the widget tree in some framework-specific XML dialect, which the engine parses and uses to construct the browser DOM that the end user actually sees and manipulates.

On the server side of the table, the distinction is a little different. An application written using a framework from the right column looks like a Web application: UI layout is expressed in terms of tags, and event handling that is not expressed in declarative terms in the layout tags is written in Java. The frameworks listed in this column offer JSF as a programming model, and data binding works in the standard way, using the JSF expression language and managed backing beans. JavaScript is involved, of course, when the application runs in the browser, but it is completely encapsulated by the framework and isn't visible to the application programmer.

The programs for frameworks in the left-most column actually don't look like Web applications any more. They present a Java API that looks a lot like Swing or SWT but runs in the browser rather than on the desktop. The developer constructs the UI by instantiating Java objects and nesting them inside one another. All event handling is done in Java. Again, JavaScript is involved, but it's not exposed to the programmer. This model has the greatest potential to be disruptive to Web application development, because it's Web programming without markup. These frameworks can sometimes even offer to run the resulting application either in the browser as a Web application, or as a desktop application that's completely independent of the browser.


Figure 3. Server-centric vs. client-centric framework table

In both server-centric models, if programmers need functionality that's not provided by the framework, they can add new widgets, and in this case they may be programming in JavaScript. But adding a new widget is not the role that the framework envisions for most of its clients; it's supposed to be the exception rather than the rule.

Does all this indicate a trend away from the browser, toward the server? A class of applications will be well-suited to server-centric frameworks. For example, a data-entry application like a travel Web site may well find enough richness in a server-centric framework to satisfy its requirements. The SWT-like API is a very interesting alternative. Applications that need wild special effects and a lot of fast event processing on the client that's not supplied in an encapsulated widget will probably gravitate toward the client side for the foreseeable future.

Pages: 1, 2

Next Page »