14.2. Progress IndicatorActivity, Feedback, Hourglass, Meter, Progress, Waiting Figure 14-4. Progress Indicator14.2.1. Goal StoryReta has made a sale and is typing in the details. She completes the credit card details and proceeds down the page to delivery dates. Meanwhile, the status area has appeared beside the credit card details. While she completes the rest of the form, the status area continues to update with the current verification stageinitially "submitted," then "responding," then "verified." 14.2.2. ProblemHow can you provide feedback while waiting for server responses? 14.2.3. Forces
14.2.4. SolutionIndicate the progress of server calls. You can't always reduce delay, but you can include a Progress Indicator to ease the pain. A Progress Indicator helps maintain the user's attention, improves the user's understanding of how the system works, and also communicates that the system is still alive even if a response hasn't yet occurred. The Progress Indicator is typically introduced to the DOM once an XMLHttpRequest Call begins and removed when the call has returned. The easiest way to detect whether the call has returned is using the XMLHttpRequest callback function. An indicator need not relate to a single callit can show progress for a sequence of related calls. Sometimes it's a Popup (Chapter 15) element instead of a new element directly on the page. A popular idiom is a small opaque Popup on the corner of the page showing just a word or two (i.e., "Saving . . . ", "Loading . . . "). For shorter delays, typical Progress Indicators include:
For longer delays, the following can be used:
Of course, you can combine these approaches. Generally speaking, some form of unobtrusive animation is worthwhile in any Progress Indicator, because it at least tells the user that something's happening, even if progress is temporarily stuck. In addition, longer delays should usually be completed with a visual effect such as One-Second Spotlight (Chapter 16), since the user's focus has probably moved elsewhere by that stage. Note that one form of indicator to avoid is changing the cursor. Many traditional GUIs switch over to a "rotating hourglass" or related icon during delays. That's probably inappropriate for Ajax because it's something the actual browser software will do tooe.g., while loading a new pageso it's likely to create confusion. 14.2.5. Decisions14.2.5.1. What sort of Progress Indicator will you use?A well known set of guidelines is summarized in Jakob Nielsen's Usability Engineering (http://www.useit.com/papers/responsetime.html). Following is a quick summary:
The precise figures may require some adjustment and I suspect a web context requires them to be dropped a bit. For example, users will probably want some feedback for a delay of 0.5 second rather than 1 second, and more detailed information is probably appropriate after 23 seconds rather than 10 seconds. Bruce Tognazzini also offers some useful guidelines (http://www.asktog.com/basics/firstPrinciples.html#latencyReduction). 14.2.5.2. How will you provide feedback during longer delays?For longer delays, you need to help the user track how much progress has been made, typically using a progress meter that shows percent complete. Sometimes, a long delay can come from a single XMLHttpRequest Call, because although the network transfer may be quick, the backend processing might not be. For example, the call might trigger a major database operation. You probably won't get any useful information about its progress by monitoring the responseText component of XMLHttpRequest. The responseText tends not to populate in a linear fashion, for two reasons. First, there are usually backend calculations involved, during which no output can occur. Thus, output tends to happen either in bursts or all at the end. Second, the output is often compressed using the standard HTTP content encoding facility, and the compression algorithm will force data to be outputted in bursts. The XMLHttpRequest's readyState won't tell you very much either. For reasons described in XMLHttpRequest Call and HTTP Streaming (Chapter 6), tracking support is inconsistent across browsers. So if you can't monitor the progress of an XMLHttpRequest Call, how can you help the user understand how much progress has been made? One thing you can do is Guesstimate: predict the total time, and start running a timer to monitor how long it has been since the call began. The prediction of total duration need not be hardcoded every time; you could have the application track download times and reflect them in future estimates. This sort of thing is quite common; e.g., in the download-time estimates given by a web browser. If you want more accuracy, introduce a second monitoring channel. While the primary request takes place, a sequence of monitoring requests are issued to ask the server for a progress estimates. For example, the server might be looping through 1,000 records, running a transformation on each and saving it to the database. The loop variable can be exposed in a second Web Service so that the browser monitoring can inform the user. Not all Progress Indicators concern a single XMLHttpRequest Call. Indeed, those requiring a progress meter are longer processes, likely incorporating several XMLHttpRequest Calls. With those, you have much better opportunity for real-time progress monitoring; each time a call returns, further progress has occurred. In a simple model, you can show that progress is 50 percent complete when two of four calls have returned. 14.2.6. Real-World Examples14.2.6.1. Amazon Diamond SearchAmazon Diamond Search (http://www.amazon.com/gp/gsl/search/finder/002-1527640-2908837?%5Fencoding=UTF8&productGroupID=loose%5Fdiamonds) is a Live Search that shows a Progress Indicator while updating the number of results (Figure 14-5). The indicator is a simple animation depicting a block moving back and forth with a "LOADING RESULTS" message. One nice design feature is the placement of the Progress Indicator on the result status. It replaces the results once searching has begun and remains until the new results are shown. Thus, it serves to invalidate the previous results at the start and focuses the user's attention on the new results at the end. Figure 14-5. Amazon Diamond Search14.2.6.2. Amazon ZuggestLike Amazon Diamond Search, Francis Shanahan's Amazon Zuggest (http://www.francisshanahan.com/zuggest.aspx)is a Live Search that shows a Progress Indicator while searching is underway. In this case, the indicator is a text message such as "Searching...beat." It occupies its own fixed area, and when searching is complete, morphs into another message: "Done!" 14.2.6.3. ProtopageProtopage (http://www.protopage.com/) is an Ajax portal. Each time you make a change, such as dragging a Portlet (Chapter 15), an opaque "Saving . . . " message appears in the bottom-right corner. This is a good model for a Fat Client application, in which server synchronization should be unobtrusive. 14.2.6.4. TalkDiggerTalkDigger (http://talkdigger.com) simultaneously calls several search engines, showing a Progress Indicator on each result panel. It's interesting because it shows how to use Progress Indicators in a Multi-Stage Download (Chapter 13) situation. 14.2.6.5. KayakKayak (http://kayak.com) illustrates how to handle a longer delay. When you search for a trip, it creates a result page with several forms of progress feedback:
14.2.6.6. The Pick'em GameThe Pick'em Game (http://www.pickemgame.com/welcome/picksheet) is an office pool game allowing you to predict this week's football winners. It provides a form where you declare a prediction and confidence level for each game. Above the form is a small instruction message, and when data is being saved, it morphs into a Progress Indicator. The indicator is a spinning disk and an "Updating Pick Sheet" message. (The demo page doesn't perform a real remote call.) 14.2.7. Code Refactoring: AjaxPatterns Progress Indicator DemoThis demo (http://ajaxify.com/run/sum/progress) introduces a progress display to the Basic Sum Demo (http://ajaxify.com/run/sum/progress). It's a simple animated GIF that shows up while waiting for the sum to return. An Img tag for the animation is present in the initial HTML: <img src="/books/2/755/1/html/2/progress.gif"> The script will toggle the image's CSS class depending on whether you're in waiting mode or not. The stylesheet ensures that it's visible when waiting and invisible when not: .waiting { visibility: visible; } .notWaiting { visibility: hidden; } With the styles defined, the script just has to flick the CSS class back and forth as the waiting status changes: function submitSum( ) { $("progress").className = "waiting"; ... } function onSumResponse(text, headers, callingContext) { $("progress").className = "notWaiting"; ... } 14.2.8. Related Patterns14.2.8.1. Status AreaA Progress Indicator is usually presented as a Status Area (Chapter 15). 14.2.8.2. PopupThe Progress Indicator can sometimes reside in a Popup (Chapter 15). 14.2.8.3. One-Second SpotlightOnce a long process has completed, use a One-Second Spotlight (Chapter 16) to point this out to the user. 14.2.8.4. GuesstimateSometimes you don't know how long a task will take or how much progress has been made so far. A sloppy guess is better than nothing at all, so make a Guesstimate (Chapter 13) of the progress. 14.2.8.5. Distributed EventsWhen a call comes in, you need to close off the Progress Indicator. There's a risk here that you'll end up with a single function that mixes Progress Indicator stuff with the logic of processing the response. Separate that logic using Distributed Events (Chapter 10). 14.2.9. MetaphorBanks and post offices often use ticket-based queueing systems, showing the number that's currently being served. 14.2.10. Want to Know More?
|