Monday, September 17, 2007

Dumping Variables

As shown in lines 1017 of Listing 7-4, there are lots of cases in JavaScript in which you have an object but don't know what properties it contains. This is especially common when you are passing JSON-encoded data from the server to the client. JavaScript provides the "for in" loop for looping over the properties of any object. Using this loop, you can construct a basic dump function that allows you to quickly see the properties of an object. Listing 7-7 shows an example function.

A JavaScript Property Dumping Function

function dump(input) {
var msg = '';
for(var i in input) {
msg += i+':'+input[i]+"\n";
}
return msg;
}

You can then use this function to alert the contents of the object or assign the debug output to a debug element on a page. A simple function like this can save a great deal of time in the debugging and development processes. Building on this same concept, the HTML AJAX library provides a utility function called varDump that provides additional information. This method is based on the var_dump function in PHP and provides the type of each element as well as its value. It also supports recursion, giving you the output of any child objects. Listings 7-8 and 7-9 show the output of varDump against different inputs. Sample usage is shown in the following code:

alert(HTML_AJAX_Util.varDump(input));

Sample varDump Output (an Array with Another Nested Inside It)
array(3) {
[0]=>
number(1)
[1]=>
array(3) {
[0]=>
number(1)
[1]=>
number(2)
[2]=>
number(3)
}
[2]=>
number(3)
}

Sample varDump Output (an Object)
object(Object) (2) {
["bar"]=>
string(3) "baz"
["bat"]=>
number(5)
}

Read more...!

JavaScript Exceptions

JavaScript has a number of language features that are useful in the debugging process. The biggest one of these is the ability to catch any JavaScript error as an exception. This is done by wrapping code that can cause errors inside of a try block followed by a catch block. In the catch block, you have access to an Error object, which contains additional information about the error. This Error object contains the name of the error and a message. On Firefox, it also includes the file in which the error happened, the line on which it happened, and a call stack. Listing 7-4 shows an example of catching an error. Listings 7-5 and 7-6 show the output of the catch block in Firefox and IE.

exception.html

1  <html>
2 <body>
3 <div id="error">
4 </div>
5
6 <script type="text/javascript">
7 try {
8 alert(IDontExist);
9 }
10 catch (e) {
11 var msg = '';
12 for(var i in e) {
13 msg += i+':'+e[i]+"<br>\n";
14
15 }
16 document.getElementById('error').innerHTML = msg;
17 }
18 </script>
19 </body>
20 </html>

Listing 7-4 is simple. It contains a basic HTML page with a JavaScript block that creates the error and then prints out the resulting error object. Lines 34 give us an element to which to write an error message. Line 7 starts the try block; it's ended by the bracket on line 9. All JavaScript errors that happen in the TRy block will cause the catch block to be run. If no error happens, the code in the catch block is ignored. The catch block on lines 1017 takes the error object and prints out each property. This text is then added to the error element, showing the value of the error object.

Output of exception.html in Firefox
message:IDontExist is not defined
fileName:http://localhost/debug/exception.html
lineNumber:8
stack:@http://localhost/debug/exception.html:8
name:ReferenceError

Output of exception.html in Internet Explorer
name:TypeError
message:'IDontExist' is undefined
number:-2146823279
description:'IDontExist' is undefined

Looking at the error messages, you can see that exceptions in Firefox are more useful for general debugging, but exceptions are still useful even without line properties because you end up knowing which block of code caused the error. They also allow you to handle the error programmatically, letting you give the user an error message or even perform a workaround instead of having your code silently break.

Read more...!

JavaScript Debugging Tools

The tools we've looked at so far are good at giving you a picture of the communication between the client and the server, but they're not a huge help if the bug is somewhere in your JavaScript code. JavaScript isn't known for having a large number of tools to help the developer, and if you're working with Internet Explorer, that lack of tools is still true; however, Firefox (and other browsers) gives you a lot of tools that are helpful with debugging and developing JavaScript. For instance, the most basic Firefox development tool is the JavaScript console (see Figure 7-17). Any JavaScript errors are shown in it, and clicking one of them will show you the line in your code where the error happened. You can view the console by selecting it from the Tools menu; it's labeled either JavaScript Console or Error Console, depending on your Firefox version. (Note that a number of Firefox extensions, including Firebug, provide quicker access to this information.)

Firefox JavaScript Console

Out of the box, Internet Explorer gives you a particularly hard time debugging JavaScript because it doesn't provide correct lines numbers when external files are used. The solution to this is to install the Microsoft Script Debugger (www.microsoft.com/downloads/details.aspx?FamilyID=2f465be0-94fd-4569-b3c4-dffdf19ccd99&DisplayLang=en). After you install the debugger, you need to turn it on. To do so, follow these steps:

1. Open Internet Explorer and go to Tools -> Internet Options.

2. Select the Advanced tab.

3. In the Advanced tab, you see an option labeled Disabled Script Debugging (Internet Explorer). Uncheck this option to enable the debugger. This debugger dialog box is shown in Figure 7-18.

Enabling the Microsoft Script Debugger

4. Once you have the debugger enabled, you receive a dialog box for each JavaScript error. The dialog box asks if you want to debug your error (see Figure 7-19). Selecting Yes will open the debugger and show you the line in the file where the error occurred.

Script Debugger Error dialog box

The basic debugger interface is shown in Figure 7-20. From this screen, you can step through the code using the Debug menu, just as with any other debugger. The debugger has two main drawbacks: It creates a popup dialog box for each JavaScript error that has to be dealt with, and it tends to become unstable when actually using it for debugging. That being said, the Script Debugger quickly gives you the actual line where JavaScript errors happen, which is a big advantage over the normal IE error message.

Basic Script Debugger interface

Read more...!

Thursday, September 13, 2007

Looking at AJAX Communications

Commonly, when you get an error, it's caused by a small problem, and all you need to do to solve it is to look at what the client sent to the server and then look at the server's response. Some libraries provide logging mechanisms to record this information, and you can easily create a generic request logger using PHP, but I find tools that directly interact with my browser to be more effective. However, you don't always have access to these tools, or you may need to debug in a nondevelopment environment. In such cases, you'll want to know how to build a logger.

Building an AJAX Logger
To build an AJAX logger, you first need to identify the information that is sent from the client. This information includes three types of information: query parameters, HTTP headers, and possibly a POST payload. In PHP, the query parameters are automatically parsed and made available in the $_GET variable; if the data sent to the server is a form submission, the POST variables are made available under a similar variable, which is $_POST. You can also read the raw POST submission by reading from php://input; this raw access is required to see the information if the client sent a JSON or XML payload. Finally, you can access the headers through the $_SERVER variable. Listing 7-1 shows an example of reading this information.

read.php

1  <?php
2
3 echo "Query (GET) parameters<br>";
4 var_dump($_SERVER['QUERY_STRING']); // raw
5 var_dump($_GET); // parsed
6
7 echo "POST parameters<br>";
8 var_dump(file_get_contents('php://input')); // raw
9 var_dump($_POST); // parsed
10
11 echo "HTTP Headers<br>";
12 $headers = array();

13 foreach($_SERVER as $name => $val) {
14 if (preg_match('/HTTP_(.+)/',$name, $m)) {
15 $headers[$m[1]] = $val;
16 }
17 }
18 $other = array('CONTENT_TYPE','CONTENT_LENGTH');
19 foreach($other as $o) {
20 if (isset($_SERVER[$o])) {
21 $headers[$o] = $_SERVER[$o];
22 }
23 }
24 var_dump($headers);
25 ?>


The query parameters are the easiest inputs with which to work; the raw version is available as an index in the $_SERVER array (line 4), and that same data turned into an array is available through $_GET (line 5). POST data is available only when a POST HTTP request has been made. This can be done by using either a form or XMLHttpRequest. The raw POST header is read from php://input (line 8), and the parsed version is on line 9. $_POST is populated only when the POST has a Content-type of application/www-form-urlencoded or multipart/form-data.

Reading the headers is a little harder because they are stored in $_SERVER along with a bunch of other data. The majority of the HTTP headers are prefixed with HTTP_, so we can display them by looping over $_SERVER and doing a regular expression match (lines 1317). This match will store the matching headers into an array. A couple of important HTTP headers don't have an HTTP prefix, so we look for the Content-type and Content-length headers using a secondary check (lines 1823).

The examples for this chapter, which can be downloaded from the book's Web site, include a small test page (test.php) so that you can see the output of this script. The output for a GET request with a query, a form POST, and a POST from XMLHttpRequest are shown in Figures 7-1 through 7-3.

A GET request with a query string

A form POST


A POST request from XMLHttpRequest

To make this code usable for AJAX logging, we just need to format the output and add the ability to write it to a file. It's also useful to let the server code log what data it is going to send to the client. The final setup is a class called logger. It has two methods: storeServer, which sets the content we're going to send to the client, and write, which puts the information in a file. Listing 7-2 shows an example of a page that generates HTML chunks for an AJAX page.

pageChunk.php
1  <?php
2 require_once 'logger.class.php';
3
4 $logger = new logger();
5
6 // create some content
7 // use an output buffer so we can log it
8 ob_start();

9 ?>
10 <p>
11 Some random content
12 It could be anything generated from PHP
13 or static like this
14 </p>
15 <?php
16 echo $_GET['input'];
17
18 // page is done
19 $logger->storeServer(ob_get_contents());
20 $logger->write();
21
22 ob_flush();
23 ?>


Using the Logger
Adding our logger is a fairly simple process. We include the logger class (line 2) and then create a new instance of it (line 4). When the logger instance is created, it automatically grabs the information from the client, so if the $_GET, $_POST, or $_SERVER variables are changed by other parts of the code, our logging is not messed up. Then, we start an output buffer (line 8). This will allow us to log what is being sent back to the client without changing any of our existing code. Lines 1016 contain some example input, and then we finish our logging process. Line 19 uses the ob_get_contents method to read all the output that has been created and to set it on our logger. Then, on line 20, we write out a log entry. The script ends by calling ob_flush (line 22), which sends out all the generated content we've been buffering. This simple logging process stores most of the details of an example entry from the log file, as Listing 7-3 shows.

LogEntry
################################################################################
Request to: /debug/pageChunk.php
Time: 2006-02-25 11:45:13

RAW Query String: input=test
_GET:
array (
'input' => 'test',
)

RAW POST:
_POST:
array (
)

HTTP Headers:
HOST:localhost
USER_AGENT:Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.0.1)
Gecko/20060111 Firefox/1.5.0.1
ACCEPT:text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,te
xt/plain;q=0.8,image/png,*/*;q=0.5
ACCEPT_LANGUAGE:en-us,en;q=0.5
ACCEPT_ENCODING:gzip,deflate
ACCEPT_CHARSET:ISO-8859-1,utf-8;q=0.7,*;q=0.7
KEEP_ALIVE:300
CONNECTION:keep-alive
COOKIE:clearhealth=fcf23cdc7394e71b5c83a9929f0fdb7e
CACHE_CONTROL:max-age=0

Sent to client
<p>

Some random content

It could be anything generated from PHP

or static like this

</p>

test
Logging like this is easy to build into the AJAX library that you are using (if it doesn't already have its own). It's easy because the process happens automatically. If you're using an HTML page chunk approach, you could also build it right into your framework; in that case, the logging could be done on a preconfigured set of pages, or it could be turned on by sending a custom header when you make a request using XMLHttpRequest. Logging like this is especially useful in large-scale testing or production environments in which you don't have access to the browser to see error messages.

Firebug: A Firefox Debugging Extension
While logging provides you with a lot of information, it's not the most efficient way to get the information you need. It means keeping another file open and parsing through large text entries for the required information. Logging also doesn't have access to what is happening to the JavaScript on the browser, so it doesn't contain the full picture. Tools that can be added to the browser can get around most of these problems and have the ability to offer you a rich user interface.

If you're using Mozilla Firefox, extra functionality can be added to your browser through the use of an extension. The Firebug extension (www.joehewitt.com/software/firebug/) adds a popup bar at the bottom of the browser that lets you see JavaScript errors. With it, you can also view details of each XMLHttpRequest request, inspect DOM elements, and run JavaScript commands against the current page. An installation link is available from the project's Web site. The basic interface is shown in Figure 7-4.

Firebug: a Firefox debugging extension

Firebug attacks the debugging process from the JavaScript side. Whenever a JavaScript error happens, an error icon is shown in the lower-right corner (see Figure 7-5). Clicking this icon will bring up the console, showing you the errors. In its default configuration, these errors include errors generated by CSS, the browser, and its extensions (see Figure 7-6). To limit the displayed errors to just JavaScript ones, use the Errors drop-down box to deselect Show Errors From Chrome and Show CSS Errors. You can also get to the dialog box even when an error hasn't happened by clicking the error icon in the lower-right corner (see Figure 7-7). Doing this gives you an easy way to get to the XMLHttpRequest inspector.

Firebug error icon

Firebug error selector

Firebug status icon

The XMLHttpRequest inspector lets you see the POST payload that was sent to the server, the response from the server, and the properties of the XMLHttpRequest object that sent it. A new row is added to the Firebug pane each time a request is made using XMLHttpRequest, so you can also use it as an overview of your AJAX activity. Each request entry includes the HTTP request type (generally GET or POST) and the URL to which the request was made. Figure 7-8 shows Firebug with several requests in it.

Firebug with multiple XMLHttpRequest entries

Now if you have a request that isn't working as expected, you can start the debugging process by doing the following:

1. Open Firebug and find the request in the pane. Requests are added to the bottom of the list, so scroll down to the most recent one. Selecting the request expands it, giving you three tabs from which to choose.

2. Select the Post tab on the right side to see the POST payload that you sent to the server.

3. Select the Response tab to see the data that the server returned.

4. Select the Headers tab to see the HTTP headers that the server returned.

Depending on the configuration of the server, you may see a large number of headers returned with the data, as in Figure 7-9. The most important ones are Content-type and Set-Cookie. Content-type has to be set to text/xml for XML-based requests to work. Many libraries also use this header to determine if the server is sending JSON that the library needs to decode, or if the content is just plain HTML. The Set-Cookie headers mark which cookies were set on this request; you can use them to verify that new authentication or other cookies were set as needed.

Firebug showing the Headers tab of an XMLHttpRequest entry; the important fields are outlined

Firebug also has the capability to run any JavaScript command against the current page. To do this, type a JavaScript command such as document.getElementByName('test').style.color = 'red'; into the field at the bottom of the page (see Figure 7-10). You can also inspect page elements, get layout information, and view all elements, DOM properties, and events (see Figure 7-11). These features are useful in the overall development processes, but the biggest aid to debugging AJAX requests is the XMLHttpRequest inspector.

Running a JavaScript command in Firebug

Inspecting a DOM element with Firebug

Fiddler
If you develop in Internet Explorer or just need to track down an Internet Explorer-specific bug, you obviously won't be able to use Firebug, but there still are a number of useful tools to help you. One tool is Fiddler, which is an HTTP debugging proxy that lets you see each request made by Internet Explorer and the response it receives from the server. Because it is an external tool, it can't look at the JavaScript the way Firebug can, but it does have an easy-to-use interface and it does give you an easy-to-use view of each request.

You can download Fiddler from www.fiddlertool.com/; this Web site also includes a wealth of information on how to use its advanced scripting and transformation features. Once you have it installed, you just need to run it, and Internet Explorer will automatically be set up to use it. You can also use it with other browsers by setting them up to use Fiddler as an HTTP proxy. You just set the proxy host to localhost and the port to 8888. An example of setting up the proxy in Firefox is shown in Figure 7-12.

Setting up Firefox to use Fiddler as its proxy

Once you've run Fiddler, open your browser and perform the request that is giving you problems. Each HTTP request is shown as an entry in the main pane; secondary requests for images and CSS files will be shown with gray text, and the two HTML pages will be shown in blue. You can clear entries from the pane by right-clicking them and selecting remove. The basic session browsing interface is shown in Figure 7-13.

Main Fiddler interface

Once you've identified the HTTP request you want to inspect, select it in the sessions pane on the left side and then look at the pane on the right side. This pane has three main tabs. For debugging purposes, the most useful tab is the Session Inspector. After you select the Session Inspector tab, the pane will be split into two sections: the top showing the information that was sent to the server and the bottom showing the server's response (see Figure 7-14). For both the request and the response, you can view the request in a number of different formats, the most useful being the Headers and TextView views. If you're using XML to move data between the client and the server, you will also find the XML view to be useful because it will show the XML data in a formatted display.

Fiddler session Inspector interface

The Headers view shows you a formatted version of the HTTP headers used in the request (see Figure 7-15). You can use this view to verify cookies are being sent, to see the Content-type of the data, and to view any HTTP status codes. The online help gives more details, but outside of verifying expected Content-types, you shouldn't need to spend much time here. The TextView view shows you the content that was sent to the server in a POST request and the results that the server sent back. The view offers the ability to search the content inline (the blue Find bar) and to open another program, such as your favorite text editor. (The open with command is the button to the right of the blue Find bar). You can see an example of the TextView in Figure 7-16. Fiddler offers a number of other features, which are useful for transforming the request and responses, but they are not all that useful in basic AJAX debugging situations.

Fiddler Headers view

Fiddler TextView view

General Debugging Scenarios
Firebug, Fiddler, and custom logging code all provide extra information about an AJAX request. These types of tools are useful in scenarios in which you make an AJAX request and the request dies without giving useful information to your JavaScript code. In most cases, looking at the response from the server will quickly point out the problem. It could be an error in your server code or just some unexpected data being returned.

Debugging tools such as Fiddler or Firebug can help you figure out what data you're sending to the server. This can be especially useful once you start using more complex JavaScript widgets and AJAX libraries. These libraries offer a lot of functionality, but they move the AJAX operations far away from the actual event. This can make it hard to see what is really happening, so by using a tool like Firebug or Fiddler, you can see the HTTP request that was sent to the server and know what is really going on.

Read more...!

Monday, September 10, 2007

Two Sides to Debugging

When you look at an AJAX application, it is important to remember that there are two sides to the equation: the server, which interacts with the back end, and the client, which adds interactivity to the user's environment. Although this two-sided model has always existed, what has changed dramatically with the rise of AJAX is the complexity of the code running on the client. A secondary complexity is the number of interaction points between the two sides. Added complexity always makes debugging harder, so your focus when debugging an AJAX application needs to be on the various ways you can reduce that complexity.



The first step to debugging any problems is to separate the two sides as much as possible. This is generally an easy process on the server side; if you are generating HTML page chunks, you can go to the URL and inspect the output, looking for errors generated by the server code. If you're using a JSON or other RPC-based approach, it's slightly harder. However, you can always check the code that is being run by the RPC call, using normal development tools to look at its state before it's encoded. Many people find unit tests to be especially helpful in verifying the operation of the server-side code. It's especially useful for applications that expose chunks of functionality as services to the client. Unit tests work well on the server side because every major language has mature tools for managing these processes, and it narrows the type of problems you'll see on the data-production side.

On the JavaScript side, unit tests have a harder time being effective. This is due both to the lack of tools and the difficulty of testing an environment that relies on user-created events. There are a number of jUnit ports to JavaScript, and by using these testing frameworks and working hard, you can successfully use unit tests on the JavaScript side as well. Unit tests are a tool, and in AJAX development, they can be powerful because they provide a framework to test both sides of the equation separately. Note, however, that they are not your only option. The most important item to remember is to debug the easy stuff first. If you get an error, always verify that your server-side code is working properly before moving on to the JavaScript.

Read more...!

Friday, September 7, 2007

Common Usability Problems

Although AJAX has the ability to create a more usable and efficient interface, it doesn't always achieve this goal. Usability problems can steal away any gains created from the use of new technology. This section discusses some common usability problems and then gives examples on how to fix them. Many of these problems can happen without the help of AJAX, but they are prevalent in AJAX applications, which are more active by nature.

Stealing Focus with Validation Messages
A common use of AJAX is to perform complex validation before the user has submitted a form. This is especially useful on large forms where large amounts of data are input before validation can take place. Simplistic attempts at continuous validation are often worse than waiting until the form is submitted to perform the validation, because they continuously steal the user's focus.

Figure 6-1 contains a basic registration form. AJAX is used to validate that the username hasn't already been taken and that the zip code matches the city/state information. The problem here is that validation steals the user's focus because it uses popup alerts to give validation errors as the user tabs to the next field.

A validation message stealing focus on a user registration page


One solution to this problem is to change from a popup error message to an inline one. In some cases, this is an acceptable solution, but it still causes problems. (In this case, the problem is that the more useful error message will cause the form to move down quite a bit in the user's view.) Although usable, this approach pushes most of the form off the user's page after a couple error messages are shown. It's also not clear which fields need to be updated. Figure 6-2 shows an inline validation message.

A validation message that pushes the rest of the form down


Figure 6-3 shows a possible solution to these problems. The size of the error messages was reduced to a single line, and the use of a "More Info" link now provides information on how to solve the error. The fields with errors were also highlighted to show what needed to be updated.

Validation messages with the usability problems fixed

Stealing focus problems often happen when trying to meet the guideline of providing user feedback. Although user feedback is important, it should not prevent the user from completing his or her current task. This is especially important when feedback is combined with automatic actions, because the user has no reason to expect the feedback to happen.

Preventing Undo with Autosave
In conventional Web applications, large forms can be dangerous because they are impossible to save automatically, and submitting the form on a regular basis depends on the user clicking a button. Plus, such saving interrupts the user's workflow. Here's an example: A content management system was upgraded with AJAX to save an article automatically every five minutes. This seemed like a great solution because then only five minutes of work could be lost by a browser crash or an accidental closing; however, after more use, a couple of problems with this approach were found.

One problem occurred when an author opened an article to edit it. He or she would make some changes and then decide, perhaps, that he or she didn't like the approach taken. In other words, the author ended up wanting to revert to the old version, but couldn't; during the editing process, the autosave process had already overwritten the original. This was not good.

As you can see from the previous scenario, editing couldn't be done on live articles because the autosave process would push out changes before they were complete. This problem can be solved easily by creating a separate autosave area to store the data from this process. This autosave area can keep anywhere from one to an unlimited number of autosaves. An interface is then added to let users load an autosave and save it as a normal version.

In some content management systems, documents are versioned so that the original problem of overwriting data doesn't happen. However, saving each autosave as a new version can also be problematic because it makes for a clumsy document history and can cause data-storage needs to explode. In a versioned content management system, a separate autosave area would also work, but it may be more useful to use a subtree in your version history to which autosaves are written. The application can then remove the old autosaves when each normal save is complete. This allows autosaved articles to be accessed by the normal article-management process without causing an explosion in version history.

Preventing undo operations often happens when AJAX implements autosave. This prevention results in data-loss situations from a process that was supposed to prevent them. Whether you are using time-based saving while editing an article or autosaving a form by detecting what field is edited, you are changing the way a Web form normally operates. Because you are moving the save decisions out of the user's hands, you need to provide a way for the user to revert his or her changes.

Updating Sections of a Page Without the User Realizing It
One way to use AJAX is to update parts of the page with new content in response to a user's action. This AJAX updating process could be used in technical documentation to load definitions or related information. A basic example of this is shown in Figure 6-4. When you click any term with a dashed link, its definition is loaded into the sidebar on the right.

Documentation Browser with no feedback

The page in the preceding figure is already taking some usability steps, such as using a different link style for definition links, but it still has one problem: No feedback is given to the user regarding the fact that something has changed. Feedback is important in this case because we are redefining a standard browser action. Normally, when you click a link, it loads a new page. If the user were expecting a new page to load and didn't notice the change on the right, he or she might think the link was just broken.

Providing feedback is about finding the right balance; we want to show that something has changed without annoying the user with effects that are overly flashy and distracting. There are a number of different techniques we can use in this case. One technique is to show a loading message while the browser is waiting for the server to respond. At this same time, we can fade out the current content and then fade it back in after the new content has arrived. Figure 6-5 shows this approach in progress.

Documentation Browser while loading new content

An alternative to providing loading feedback is to wait until the new content is loaded and then highlight it in a pale yellow background. Over a period of three to five seconds, this yellow then fades to the white background color. Figure 6-6 shows the beginning of this process. In a documentation browser, I would recommend this approach because it doesn't distract the user until there is actually something to see. However, in another application where the content may take a while to load, immediate feedback would also be needed. You could combine both approaches, but in most cases, a more subtle approach is just as effective and is more aesthetically pleasing.

Highlighting content to provide feedback that the content has been updated

Breaking Bookmarking by Using AJAX to Load Entire Pages
Many times, when developers adopt a new technology, they see it as the solution to every problem they have. One area where AJAX can be overused is as a replacement for HTML framesets. This AJAX usage allows you to skip the loading of the navigation sections and just update the main body of the document. However, unless you take steps to make bookmarking work, you have the same problems as using framesplus a more complicated development process. Figure 6-7 shows an example of this mistake; here, everything below the navigation bar is loaded using AJAX.

Loading an entire page using AJAX

In most of these cases, the simple solution is to use only normal pages; because navigation is seldom a large part of a page's loading time, these approaches save little in load times. In other cases, you may find that trying to load entire pages using AJAX is just a symptom of larger design issues, and you'll need to start at the beginning and focus on how users will interact with your information. AJAX is a great tool, but it is not the solution to every problem. Design and development should always keep the user in mind. The end result might not use every technology you would like, but it will make for the best user experience.

Making AJAX Required on a Web Store
Although AJAX adds great capabilities to a Web site, it's not always worth the cost. The biggest cost is preventing users from using a site because they're not using an advanced-enough Web browser. While it's easy to say "Please upgrade," doing so is not always possible, especially if the user is using a mobile device, such as a PDA or cell phone. Let's look at a fictional scenario to see some of the problems that might be caused by requiring AJAX. A Web-based store updated its shopping cart to use AJAX; it then tested AJAX on all the major browsers, and everything worked fine. Because the store was supporting all major browsers, it decided to drop its non-AJAX version. After rolling out the new shopping cart, a large number of complaints came into the company's support email. After some research, the store noticed that all the complaints were from users using Pocket IE on smart phones or PDAs.

This is a fictional example, but it shows important points. Although no new computer will come with a browser that can't be used with AJAX, lots of mobile devices still will. If your site has a broad user base, requiring AJAX may shut out a sizable part of your audience.

Read more...!

Usability Guidelines

Many usability experts have criticized AJAX by pointing out cases where it hurts usability. Although it is possible for AJAX to have that effect, I don't think AJAX inherently hurts usability; it's just that many developers have the wrong focus when adding AJAX to their sites. Focus on buzzwords and the latest technology results in nice demos but not necessarily in easy-to-use sites. Web development should always be user focused; adding AJAX to the mix shouldn't change that.



As you use AJAX, keep the following guidelines in mind, and you'll end up with a highly usable site or Web application:

  • Keep the user's expectations in mind

  • Provide feedback to actions

  • Maintain the user's focus when adding content

  • Keep the ability to undo actions

  • Know if you are developing an application or a Web site

  • Only use AJAX where it has the greatest effect

  • Have a plan for those users without XMLHttpRequest

The following subsections cover each of the points in more detail.

Keep the User's Expectations in Mind

Keeping the user's expectations in mind is a broad guideline, but it is also an important one. At the simplest level, it means not changing how things operate without letting the user know. In most Web pages, buttons are used to submit forms, so having some other action, such as the clicking of a hyperlink, to submit a form can be confusing to users. This rule comes into play in any place where you redefine the standard way a Web site works.

One area in which you'll have a hard time meeting expectations is with bookmarking and the Back/Forward button operations; in many cases, these will no longer work, and you'll need new ways to support bookmarking within your application. This guideline doesn't mean that you have to change how the user interacts with your site; it just means that you need to work to provide the user with enough feedback so that he or she knows what is going on.

Provide Feedback to Actions

The next guideline focuses on providing feedback that an AJAX action has taken place. With this feedback, users know that some action has happenedeven if it doesn't work as expected. In a basic Web application, the page reload shows that something is happening. In an AJAX application, we remove the reload, so we need to replace this feedback. This feedback mechanism ranges from a loading message in the corner of the screen that is similar to the waving flag that Internet Explorer uses to visually highlight the sections of the page that have changed. In many cases, you'll want to use multiple approaches, such as showing a standard loading box while the new content is being transmitted and then highlighting the part of the page that was updated. Providing feedback keeps your application from feeling broken. When someone clicks a link, he or she expects something to change; without the feedback, it's easy to miss what happened.

Maintain the User's Focus When Adding Content

As you add feedback to your AJAX application, avoid disturbing the user's focus. This usability guideline is especially important when using popup messages; they should never be used except in areas where immediate action is required.

Here are some items to watch out for when thinking about maintaining a user's focus on one area:

  • Actions that move the focus of a cursor. Such actions will cause the user to type in the wrong input box or have to take the time to figure out the current cursor location.

  • Actions that cause page reflows. If a user fills out a form and an error message causes the form to move down half an inch, the effect can be disorienting.

  • Distracting message styles. Blinking red text can steal the user's focus just as easily as a popup can.

As a user interacts with your site, remember that he or she controls the interaction, not you; if your message isn't important enough to require immediate action, don't push it into the user's focus prematurely.

Keep the Ability to Undo Actions

Many AJAX applications try to outthink their users by automatically saving data as needed or submitting a form without clicking a button. When this is done well, it can be effective, but you must keep the user's expectations in mind when applying these techniques. Users are used to a forgiving Web environment where they can simply reset a form if the current input is incorrect. As you add AJAX, you must keep that level of forgiveness; operations should always be undoable. Autosave is one of the worst offenders in this area, but it is easily fixable by adding a Reset button on an autosave form or exposing the history of the saves.

Know If You Are Developing an Application or a Web Site

As you develop with AJAX, it is important to know if you are creating an application or a Web site. If you are developing an application, focus on having it act like a native application; following the human-interface guidelines of the target operating system is often a good idea. If you are developing a Web site, strive to have your work fit the standard feel and interaction model. This focus helps set the user's expectations and will make your interface more learnable because the user will have a correct frame of reference against which to compare it.

Only Use AJAX Where It Has the Greatest Effect

AJAX is a powerful tool, but it should be only a part of your Web development arsenal. Always make sure not to overuse AJAX. It should be used in areas where its extra capabilities provide enough benefits to overcome its drawbacks. An example of such an area is the breaking of bookmarking within a page. AJAX is a great tool to update part of a pagejust load the changed contentbut it should not be used to load an entire page. Normal pages work just fine and are going to be just as fast as reloading the page with AJAX. When you are deciding on using AJAX, look for a problem that needs solving, not just for places where it might be possible to use AJAX.

Have a Plan for Those Users Without XMLHttpRequest

The last usability guideline is to have a plan for users whose browsers can't perform AJAX operations. No matter how usable an application is, if the user can't run it, it's useless. For internal applications, this is seldom an issue because a specific browser can be required, but that's not always a great idea for a mass market Web site. If you're using AJAX just to enhance slow tasks, an easy solution is to keep support for the slower non-AJAX operation. However, if much of your site depends on AJAX, you will need either to create a non-AJAX version or to keep non-AJAX users out of your site. Users who use browsers that don't support AJAX should always at least get messages that some actions won't work for them. As you add AJAX, make sure to understand your audience. Although AJAX is widely supported, it won't work in all browsers (especially mobile ones), and you don't want to lock out any part of your audience without addressing the consequences.

Read more...!

Defining Usability

Usability is defined by the International Organization for Standardization (ISO) in document 9241 as "the extent to which a product can be used by specified users to achieve specified goals with effectiveness, efficiency and satisfaction in a specified context of use." For our purposes, this broad definition boils down to this: Can people easily understand and use your Web site?

Usability expert Jakob Nielson has a framework for looking at the usability of a Web site. It breaks down usability into five components: learnability, efficiency, memorability, errors, and satisfaction. By using this framework, we can identify usability problems in AJAX designs and identify ways to solve them:

  • Learnability looks at how easy it is to accomplish tasks the first time the user visits the site. Learnability can be a problem in many AJAX designs because the site no longer acts like a standard Web site to which the user is accustomed. These problems are most common when the results of standard actions are changed. Creating new widgets can also be a problem, although this can be alleviated by making the new widgets look like their counterparts in the standard application world. Simplicity and consistency are keys to making an interface learnable. The goal isn't to make a flashy unique interface; it's to create one that new users can instantly recognize.

  • Efficiency refers to how quickly the user can perform a task once it has been learned. This component sometimes stands in juxtaposition against learnability because the most efficient interfaces may require a large amount of knowledge to use. (A text-based data entry system is one example of an efficient interface.) Efficiency is the area of usability where AJAX can make a huge difference. AJAX can combine multistep processes into one quick screen to greatly reduce the time required to complete a task. This savings is most obvious in item-selection cases where multistep popup search screens can be replaced with search-as-you-type AJAX widgets.

  • Memorability looks at how easily a user can regain proficiency in the use of the interface after not using it for a period of time. In such situations, the use of AJAX might not have a large effect, but it still can make a difference. AJAX can be used to streamline processes, which reduces the amount of steps that the user has to remember. It can also be used to create unique interface widgets that may hurt memorability because the user has no points of reference for them.

  • The errors component focuses on having a system with few errors. It also focuses on how easy it is to recover from errors that are received. Web development as a whole is prone to network-related errors, but these errors are seldom fatal because users can just reload their browsers. In an AJAX application, network errors will need to be trapped in application code because the browser's Reload button won't resend the AJAX action. The greater use of JavaScript can also create more errors if developers aren't used to the language. One way to help alleviate these problems is to use an AJAX library that simplifies cross-browser development.

  • The final component is a subjective measurement of satisfaction. Does the user enjoy using the design? This component is affected by many items, especially visual design, but AJAX can still play a part. A highly efficient AJAX interface that provides good feedback about what it's doing will be more satisfying than a standard, slow Web interface that requires tons of page reloads.

Read more...!

Wednesday, September 5, 2007

Promises and Problems of Combining AJAX with Other New Technologies

As you work with AJAX, you may hear of related technologies that you can use with AJAX. They fit into two main groups: mature technologies that are widely available in many browsers today, and new technologies that are available only on a specific browser. The mature technologies include Java and Flash. (Flash is the most important because its plug-in is widely installed, and its design is optimized for providing interactive elements and animations to Web sites.) Java can also be used to add interactivity to sites, but its popularity has waned over the past five years, and it's no longer installed by default everywhere.

Combining AJAX with Flash
Flash makes a good partner with other AJAX techniques because it provides a number of features that are not available with pure JavaScript. These include a canvas on which images can be added and positioned and a drawing API that can be used for creating graphics. In addition, Flash has the ability to stream video and sound, and it includes support for vector animations. The biggest drawback of Flash is that it adds a new, separate development environment, and although you can make calls between the JavaScript on your page and the ActionScript of your Flash movie, it's not tightly integrated with the rest of your page. Flash also has a different look than the rest of the elements on an HTML page, which makes it hard to deliver a consistent feel and operation when using it for small elements within a bigger picture.

The drawbacks of Flashpoor JavaScript integration and a different look and feelare not insurmountable, but they do lead many people to pick a complete Flash solution when they need to do anything complicated. This helps control complexity, but it leaves you fully tied to a single vendor and means that you have to use Flash remoting for your communications layer instead of AJAX. Adding Flash to your AJAX application gives you the ability to support many graphical tasks that would be impossible without it, but be prepared for a more complex design and debugging process.

Scalable Vector Graphics (SVG)
The new technologies in the browser world are not as widely deployed as Flash, and some, like Microsoft's Extensible Application Markup Language (XAML), have had only beta releases. They do have the benefit of being fully integrated into the browser, making them fully scriptable with JavaScript and available as first-class elements on Web pages. Scalable Vector Graphics (SVG) is a new W3C standardized language for creating vector graphics. It has many of the same features as Flash, allowing for animations and interactive graphical elements to be added to the page. SVG avoids many of Flash's problems because it uses JavaScript for scripting; in addition, it can be embedded directly into an HTML page and modified just like any other element.

SVG's biggest problem is that browser support has been slow to develop; a plug-in from Adobe currently supports many of its features, but it leaves some of the same integration problems as Flash. The next versions of both Firefox and Opera browsers will have built-in support for SVG, but that still leaves it as a niche technology that can be used only on internal projects.

SVG is also missing a canvas element, so there is no way for users to draw on elements, as can be done with Flash. To address this, a bitmap canvas was created by Apple for its Safari browser. This effort has since been codified by the Web Hypertext Application Technology Working Group (WHATWG). This group is supported by many browser developers, including Mozilla and Opera, so support will be forthcoming in new releases of these browsers; however, support by Internet Explorer seems less certain.

XML User Interface Languages
Many of the new technologies are missing widespread browser support, and XML-based user interface languages are no exception. These languages, which include Mozilla's XML User Interface Language (XUL) and XAML, add the ability to describe normal application elements (such as menus, scrollbars, text boxes, and buttons) in an easy-to-use XML markup. Microsoft and Mozilla built their XML languages to allow for the creation of highly interactive rich applications that look and feel much like native applications right out of the box. However, because they are supported only by a single vendor, they do create problems of lock-in and tie you to a specific browser. This lock-in makes for a much less compelling solution than widely compatible solutions built on top of JavaScript and HTML.

XUL was created to define the user interface of Mozilla's browser and has been available for a number of years. Recently, it has begun to gain momentum as Firefox has increased in popularity, but it will never be able to move beyond niche products until other browsers support the language. XAML was created by Microsoft as part of its .NET effort, and it is scheduled to be released as part of Windows Vista. It's hard to know what its effect will be until it's widely released and until we know how accessible it will be to Web developers.

The rise of popular new Web browsers has led to the creation of exciting new Web technologies. The biggest problem is that most haven't made it beyond being implemented in a single browser. As support for these new technologies increases, they may become larger players, adding in the technology needed to increase interactivity beyond the level that AJAX and dynamic HTML (DHTML) can reach on their own.

Read more...!

Tuesday, September 4, 2007

Measuring Improvements

Measuring the time it takes to complete a task is one of the most useful metrics when looking at the success of an AJAX implementation. The actual measurement process is broken down into three simple steps:

1. Identifying a task's starting and ending points

2. Adding instrumentation to measure the starting and ending times

3. Combining multiple data points into useful information

Deciding which tasks to measure is generally a simple process; you need only find the areas in the application about which users always complain. If a process is slow and clunky, it's a good target for AJAX and therefore a good target for measurement. After choosing the task you need to measure, identify its starting and ending points. It's important that you measure the entire process. You don't want to focus on page loads or the technical pieces, but actual steps taken by the user. If the process is complex, you may find it useful to watch users in action to see how things are actually done.

Once you've identified the start and end points, you need to add instrumentation. In most cases, you can do this by making some simple AJAX requests to a recording script. One call marks the beginning of the process, and a second records the ending. In our example case, we'll be recording the time it takes to select a user to edit, as shown in Figure 5-5. This example is extremely artificial, but useful, because the goal is to show how to instrument a process, not how to build an AJAX user editor.

Selecting a user

The breakdown of this task is as follows: Load the page, search for a user, and then select the user from the results. The start of this task could be considered the loading of the page or the clicking of the Search for User button. In our example, we use the clicking of the Search for User button because it will help reduce the amount of variance in our measurement. The end of the process occurs when the selectUser JavaScript function runs; in an actual implementation, this would either redirect us to a user editor or populate an editing form below the selection section. A unique ID will also need to be created so that the start and end times can be matched together, but as long as the client is making only one request at a time, this ID can be created and stored in our data-storing script.

To implement the instrumentation, we will be using our basic HttpClient XMLHttpRequest wrapper. We will be making an AJAX call to process.php at the beginning and the end of the process. process.php will store this data in the session, and then process.php's endProcess function will match it with a second end request that happens when the process is complete. A simple report (see Figure 5-6) can then be run to see how long each attempt to select a user took. The data storage is basic in this implementation and would need to be replaced with a database if you wanted to collect data from multiple machines.

The reusable parts of the measurement process are the process.php storage script shown in Listing 5-1 and the Monitor JavaScript class shown in Listing 5-2.

process.php
1  <?php
2 session_start();
3
4 if (!isset($_SESSION['data'])) {
5 $_SESSION['data'] = array();
6 }
7 if (!isset($_SESSION['id'])) {
8 $_SESSION['id'] = false;
9 }
10
11
12 function startProcess() {
13 if (!$_SESSION['id']) {
14 $now = time();
15 $id = uniqid('m');
16 $_SESSION['id'] = $id;
17 $_SESSION['data'][$id]['start'] = $now;
18 $_SESSION['data'][$id]['name'] = $_GET['process'];
19 }
20 }
21
22 function endProcess() {
23 $now = time();
24 $_SESSION['data'][$_SESSION['id']]['end'] = $now;
25 $_SESSION['id'] = false;
26 }
27
28 function printStats() {
29 echo "<table border=1><tr><th>Name</th><th>Start Time</th>
30 <th>Run time (seconds)</th></tr>";
31 foreach($_SESSION['data'] as $process) {
32 echo "<tr><td>$process[name]</td><td>".
33 date('Y-m-d H:i:s',$process['start']) .
34 '</td><td>';
35 if (isset($process['end'])) {
36 echo ($process['end'] - $process['start']);
37 }
38 echo '</td></tr>';
39 }
40 echo "</table>";
41 }
42
43 switch($_GET['action']) {
44 case 'start':
45 startProcess();
46 break;
47 case 'end':
48 endProcess();
49 break;
50 case 'data':
51 printStats();
52 break;
53 }
54 ?>


Listing 5-1 uses a PHP session to store its data, so the script starts out by setting this up. We start the session on line 2 and then set some default values on lines 49. Lines 1241 define three functions, one for each of the actions the script can take. The startProcess function (lines 1220) first checks if we have a current ID stored in the session; this check allows us to ignore multiple start requests for the same process. If there isn't a stored ID, startProcess stores the current time, creates a new random ID, and then puts this data, along with the process name, into the session. The endProcess function (lines 2226) stores the current time as the end time and then clears out the ID to allow another process to start. These two functions provide the basic data-gathering capabilities of the script.

The third function, printStats (lines 2841), creates a table that provides basic reporting. It loops over the data stored in the session and creates an HTML table. While doing this, it uses the start and end times to calculate how long each process took. The output from this function is shown in Figure 5-6. Lines 4353 control which of the functions is called. The function to call is selected by the GET variable action. On the HTML side, JavaScript monitoring code makes AJAX requests to process.php to store the usage data.

simple report of how long attempts to select a user took


Monitor.js

1  // Class for monitoring time users spend performing actions
2
3 function Monitor() {
4 this.httpclient = new HttpClient();
5 this.httpclient.isAsync = true;
6 this.httpclient.callback = function() {};
7 }
8 Monitor.prototype = {
9 startProcess: function(name) {
10 this.httpclient.makeRequest(
11 'process.php?action=start&process='+name);
12 },
13 endProcess: function(name) {
14 this.httpclient.makeRequest(
15 'process.php?action=end&process='+name);
16 }
17 }


The monitor class is quite simple; it sets up an instance of HttpClient for asynchronous operation in its constructor (lines 37) and then defines two functions. The first startProcess sends a request to process.php, which triggers its startProcess function. The second function, endProcess (lines 1316), sends a similar request to process.php, but this time, the AJAX request triggers the matching endProcess PHP function. The main purpose of this class is to make it easier to instrument application pages, so it takes care of the boilerplate code for you. It is also a good place to add other methods if you find yourself needing to collect other data, such as which actions a user performs.

Now that we have a basic instrumentation framework set up to collect process times, we need to add it to a script. The process-time data can be useful in AJAX-driven pages to collect data that is generated by changes you are making. It is also useful in non-AJAX pages to help measure slow processes and to find ones that should be updated. Data collection like this can also be useful in making decisions on what data to prefetch, but normally, more data than simple timings is necessary because you need to identify which actions the user is most likely to perform. Listing 5-3 shows a simple user-selection script that uses the Monitor JavaScript class from Listing 5-2 to record how long each selection takes.

selectUser.class.php

1  <?php
2 /**
3 * This is an example class, which searches for a user from an array
4 * In most cases this class would actually query a database
5 */
6 class selectUser {
7
8 var $users = array(
9 1 => 'Joshua Eichorn',
10 2 => 'Travis Swicegood',
11 3 => 'Random Person 1',
12 4 => 'Random Person 2',
13 );
14
15 function search($input) {
16 $ret = array();
17
18 foreach($this->users as $key => $name) {
19 if (stristr($name,$input)) {
20 $ret[$key] = $name;
21 }
22 }
23 return $ret;
24 }
25 }
26 ?>


The actual searching takes place in a related class, selectUser. This class does all its searching against an array to keep the example as simple as possible, but in most cases, this process would be database-driven. The class has a single method search (lines 1524), which takes an input. The method then case-insensitively checks this input to see if it exists in the array of any of the users stored in the class. Last, the method builds an array from the matching results and then returns this array. The HTML user interface is built in Listing 5-4, which uses the selectUser class to handle POST requests to the page.

selectUser.php
1  <html>
2 <head>
3 <title>Select User Non AJAX</title>
4
5
6 <script type="text/javascript" src="HttpClient.js"></script>
7 <script type="text/javascript" src="Monitor.js"></script>
8 <script type="text/javascript">
9 var monitor = new Monitor();
10 function selectUser(el) {
11 alert('Selected User with an id of: '+el.value);
12 monitor.endProcess('Select User');
13 }
14 </script>
15 </head>
16 <body>
17
18 <div id="HttpClientStatus"></div>
19
20 <h1>Select a User</h1>
21
22 <form action="selectUser.php" method='post'>
23 <input name="name" onclick="monitor.startProcess('Select User')">
24 <input type="submit" value="Search for User">
25 </form>
26
27 <?php
28 require_once 'selectUser.class.php';
29
30 if (isset($_POST['name']) && !empty($_POST['name'])) {
31 $users = new selectUser();
32 $results = $users->search($_POST['name']);
33
34 foreach($results as $key => $val) {
35 echo "<input type='radio' name='user' value='$key'".
36 "id='user_$key' onclick='selectUser(this)'>".
37 "<label for='user_$key'>$val</label><br>\n";
38 }
39 }
40?>


The script starts with some basic setup; then, line 6 includes the XMLHttpRequest wrapper, and line 7 includes the JavaScript Monitor class. Line 9 creates an instance of the Monitor class so that we can easily call startProcess and endProcess throughout the page. Lines 1013 define the JavaScript function that is called at the end of the user-selection process; this function just outputs a selected message and then runs endProcess. Lines 2025 provide the basic HTML UI of the page; this is a form that POSTs its results to the current page. The search input box runs a start process when you click it to start entering your search term.

Lines 2740 perform the search after the form is POSTed to the page. An instance of the selectUser class does the actual searching. The results from this search are then looped over, creating a radio button for each result. An onclick action is added to each radio button, which calls the selectUser function defined in lines 1013.

The basic workflow of this page is shown in Figure 5-7.

1. The user clicks the Search input box, sending a startProcess request.

2. The user clicks the Search for User button, POSTing the form.

3. The script uses the name sent in the POST request to build a list of radio buttons from which the user can select a specific user.

4. The user clicks a radio button, sending an endProcess request.

Workflow measuring how long it takes to select a user

Data collection is an important first step to making good decisions about how and when to implement AJAX. If the user-selection process is already fast, it doesn't make sense to spend time adding AJAX to it; instead, you'll want to find a different process to upgrade. If the process is slow, you can build an AJAX version that adds instrumentation to it and then obtain real numbers on how effective the process is. Ultimately, you may find that an AJAX version of the form won't give you the increased speed that you need, because searching by name doesn't scale to the number of users in your system; instead, your best results might be accomplished by limiting the search results using other criteria, such as department or job title.

Read more...!

Sunday, September 2, 2007

Goals of AJAX

First and foremost, AJAX is about improving user experience; user experience improvements fall into two categories: making current tasks easier and making previously impossible tasks possible. Obviously, it is easier to focus on making current tasks easier. In Web development environments, this can be further broken down into two main goals: increasing interactivity and decreasing the time required to perform a task. In nonintranet cases, you may also have a related technical goal of reducing bandwidth use; by transferring less data to the browser, you can reduce page load times and improve the user's overall experience.


Increasing Interactivity

One of the overall goals of adding any amount of JavaScript to a Web site is to increase its interactivity. Even without AJAX, you can provide content-sensitive information when the user moves over a link or validates a form without reloading the page. This extra interactivity provides more information to the users without overwhelming them. Using AJAX, we can build on this general process instead of focusing on adding extra static information; in other words, we can add extra information dynamically.

A good example of increasing interactivity is using AJAX to add a real-time search to a normal search form on your Web site. An example of real-time search is the Google Suggest application (www.google.com/webhp?complete=1&hl=en), which suggests possible search terms in a drop-down widget as you type your query; the widget would also indicate the number of results the search would return. Using Google Suggest to search for AJAX is shown Figure 5-1. Similar approaches can be used for any search application. The possibilities range from selecting a user on which to change permissions to picking a city to which to send a package.

Using Google Suggest to search for AJAX

You can also use AJAX to increase interactivity in ways other than search methods. One way is to use a scrollbar to move through a page of results instead of using the Web method of next page links. AJAX works well for items such as these because data is still loaded only as needed, just as with a normal table, but the later rows can be accessed much more quickly. Figure 5-2 shows a standard table paging widget, whereas Figure 5-3 shows a table using an AJAX scrollbar instead. The example in Figure 5-3 also allows columns to be sorted without loading the page. AJAX-based filtering could also be added to the table, making for a quick and natural data-browsing experience.

A standard table paging widget for a Web site, with each link causing a page reload

AJAX-based scroll table with new data being loaded by moving the scroll bar

AJAX opens up lots of new ways to increase interactivity because the extra data you're showing can be loaded as needed. This becomes especially useful when working with medium-sized data sets, because you can see all the data without increasing the original page-load time or needing another reload to see the data. The biggest problem with increasing interactivity is that it is hard to measure, so increasing interactivity becomes most useful when looked at when addressing our secondary goaldecreasing the time required to perform the actions.

Decreasing the Time Required to Perform Actions
One of the biggest disadvantages of Web applications is that any multistep process becomes a multiminute process. On a fast connection, each page-reload connection adds two to five seconds of pure wait time as the next page is generated and downloaded by the browser, and on a slow connection, the waits can be double or triple that. Using AJAX to load in the new data allows us to remove these page reloads, making for a seamless experience with only a small one- or two-second wait for extra data.

There are lots of other cases where AJAX can be used to decease process times. They include using multistep wizards and reviewing and updating online content. Once you've found a task that takes a long time, such as moderating posts on a customer support forum, you look for the specific subtasks that take up the most time. In forum moderation, the problem is that each page reload takes a long time because you may be looking at 20 or 100 posts at once. Moderating posts requires one reload to start editing and then one reload to save your edita painful process. Other tasks, such as moving a post, are also slow because each page reload can make you lose your place in the list of posts.

For example, consider a conference-room booking system at a large company. After a room is chosen, each participant needs to be searched for and added to the booking so that he or she can receive a notification email. Because the company has over 100 employees, a select drop-down widget isn't a good choice. Using it would greatly increase page load times because so much data would need to be preloaded. An extremely large drop-down widget would also be unwieldy to use.

The solution to this selection problem prior to AJAX was to add a search system to find each employee; the search system might even be put in a popup window to lower the amount of data to be reloaded, but no matter how it is implemented, adding each person becomes a 5- to 30-second process. This clunky interface isn't a problem when adding 1 or 2 people, but it becomes unbearable when adding 20 or more. An AJAX approach allows the search to happen using a real-time search. The interface would look much like Google Suggest in Figure 5-1, displaying employees' names instead of search terms. In this case, by using AJAX, we make adding 20 employees a 1-minute process instead of a 5-minute process.

Using AJAX, you speed up the process by adding in-place editing and by using drag-and-drop to move a post. In-place editing works by creating a text editing box without reloading the page. Because the content is already displayed, no request needs to be sent to the server to start an edit. At the end of the process, the changes are transparently saved while the user moves on to editing the next post. An example of using inline editing is shown in Figure 5-4. Drag-and-drop moving of posts is also a large time-saver, mainly because it's much easier to see the target location on your normal post-browsing screen than it is to see it in a list of post titles that a non-AJAX process would be forced to use.

In-place editing

One of the things that make reducing task time such a great AJAX implementation goal is that it is easily measurable. All you need to do is sit down and perform some of the tasks and track the amount of time they take to complete. Depending on the tasks, you can even add timers to the application to record normal-use data. Once you have these baseline numbers, you can create specific targets for your AJAX implementation. Combined with further tracking after you've created an AJAX implementation, you can obtain data to decide how effective your enhancements have been. With a real and repeatable measurement, the effectiveness of AJAX moves from guesswork to simple math. You can even use this process-time measurement to improve on your current AJAX use, swapping out techniques or adding in prefetching to make a process take less time.

Reducing Bandwidth Use
Reducing bandwidth use can be a useful goal in some AJAX implementations because a smaller amount of data takes less time to transfer, providing the user a more seamless experience. If you're paying for hosting, reducing bandwidth use can also be an effective way to save money. However, if you're using your application on an internal network, this may be a goal that doesn't matter at all because the fast network keeps load times low no matter how much data you transfer.

Bandwidth use is easy to measure; the related metrics are always easier to use than subjective comparisons. Of course, unlike the measurement of time to perform a task, bandwidth use isn't a number that you always want to see decrease as a whole. Reducing the amount of data loaded in the initial page load can be useful, especially if that data is seldom used and can be easily loaded as needed. However, in some cases, the best user experience is achieved by preloading data and increasing the overall bandwidth use.

You can preload data directly during the initial page load or by using AJAX call, but you'll find that using AJAX is beneficial as long as the data isn't needed immediately. AJAX preloading can happen after the page is loaded, making it less noticeable to the user. It can also be tied to the beginning of a task that will use it. This is especially true when browsing large data sets because they generally have consistent access patterns that can be discerned by monitoring the users of the applications.

AJAX doesn't have guaranteed bandwidth reductions and, in some access patterns, it will likely use more bandwidth. This is especially true when you're performing event-driven AJAX requests. Each request may be small, but a search for each keystroke can quickly add up. These effects may be reduced by limiting the number of events to one per time period, but the effects will still build up over time. Your goal should be to make each request as small as possible, while realizing that these bandwidth reductions may be eaten up by the greater quantity of requests and by using prefetching to make a highly interactive interface.

Creating Rich Applications
Our first three goals focused mainly on making enhancements to current Web applications; however, AJAX also gives us the possibility to create an entirely new class of Web applications. When creating rich applications, developers have the goal of making them work as much like native applications as possible, while trying to keep Web development's advantages in ease of deployment and implementation. In addition, rich applications development still has the goal of increasing the interactivity of the application and decreasing the time needed to perform actions, although the design and implementation of these goals may be different.

Because you're not taking a current application and fixing slow spots, you don't have the baseline metric of a standard Web application. Instead, you have to compare your application against its native equivalent. This can be challenging because native applications can use large persistent data stores to reduce the number of slow interactions, whereas AJAX applications are limited to smaller session-based caches. Depending on how data-intensive the task is, you may be unable to match the performance of a native application, so you'll need to focus on different usage patterns that will hide this problem. The easiest native applications to mimic are those that deal with a large dataset that isn't stored fully on the local client; because the data-access speeds are similar, the Web application needs to compete only on the quality of its user interface.

Many rich applications use more bandwidth than their standard Web application counterparts because they rely heavily on prefetching data to give a seamless user experience. This makes rich applications better suited for internal deployments where a fast network and the lack of bandwidth charges remove bandwidth reduction as a necessary goal.

The decision to build a rich application instead of an enhanced Web site should not be taken lightly. Rich applications work best when they are targeting the tasks performed by a native application. Email clients, RSS readers, and reporting applications are good examples of native applications that are easy to mimic. That being said, services normally provided by Web sites, such as shopping at an online store or displaying product information, don't translate well to rich applications. These tasks are better suited to an enhanced Web site where only the slow, complex tasks are replaced with AJAX versions.

Read more...!