Progress Indicator - Ajax Patterns

Progress Indicator

From Ajax Patterns

Evidence: 3/3

Tags: Activity Feedback Hourglass Meter Progress Waiting


Contents

In A Blink

Live search - progress


Goal Story

Reta 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, a new status area has appeared beside the credit card details. While she completes the rest of the form, this status area continue to update with the current verification stage - initially "submitted", then "responding", then "verified".


Problem

How can you provide feedback while waiting for server responses?


Forces

  • Ajaxian applications often make XMLHttpRequest Calls to query and update the server.
  • Unlike standard page reloading, the browser doesn't make it obvious that an XMLHttpRequest Call is occurring. There usually won't be any information in the status area and the "throbber" (that is, the icon that normally shows loading activity, such as the "e" at the top-right of IE) will not throb.
  • There's a geographical component to server call delays. To provide good feedback, you should provide an idea of which page elements are affected.
  • Users like to feel in control, and that control is taken away when the user's waiting for a response. It's not just the delay that should be minimised, but the perceived delay.



Solution

Indicate the progress of server calls. You can't always reduce delay, but you can adopt 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 the call has returned is in the XMLHttpRequest callback function. An indicator need not relate to a single call - it can show progress for a sequence of related calls.

Sometimes, it's a Popup element instead of a new element directly on the page. An increasingly popular idiom is a small opaque Popup on the corner of the page showing just a word or two.

For shorter delays, typical progress indicators include:

  • A small message like "Updating document".
  • An animated icon.

For longer delays, the following can be used:

  • A meter showing how much progress has been made.
  • An estimate of time remaining.
  • A sequence of messages indicating what's happening at present.
  • Content that's engaging but not directly related to the progress, such as Tip of the Day or a canned graphical depiction of system activity.

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 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, 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 browser software will often do, e.g. while loading a new page, so it's likely to create confusion.


Decisions

What sort of progress indicator will you use?

A well known set of guidelines is summarised in Jakob Nielsen's Usability Engineering. As a quick summary:

  • If the delay is less than 0.1 second, the user will feel it's instantaneous. No feedback necessary.
  • If the delay is between 0.1 second and 1 second, the user will notice it but it won't break their flow of thought. No feedback necessary.
  • If the delay is between 1 and 10 seconds, the user's flow of thought is interrupted as they await the response. Basic feedback necessary, i.e. an indication that a delay is occurring. Ajax examples include animated icons and simple text messages.
  • If the delay is greater than 10 seconds, the user will want to proceed onto other tasks. Detailed feedback necessary. Ajax examples include progress meters and messages showing current state.

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 seconds rather than 1 second, and more detailed information is probably appropriate after 2-3 seconds rather than 10 seconds.

Bruce Tognazzini also offers some useful guidelines.

How will you calculate the proportion of a task that's complete?

For longer delays, you need to help the user understand how much has been achieved so far, 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 back-end 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. The responseText tends not to populate in a linear fashion, for two reasons. Firstly, there are usually back-end calculations involved, during which no output can occur. Thus, output tends to happen in bursts, or all at the end. Secondly, 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 also won't tell you very much. For reasons described in Call Tracking, you can only rely on states 0 and 4, and maybe 1.

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 since the call began. The prediction of total duration need not be hard-coded every time; you could have the application track download times and reflect them in the estimates next time round. It's possible the actual time will exceed your estimate, and you wouldn't want to show a progress of 120% while the download's still in progress. You also don't want to suddenly drop the progress percentage by increasing the time estimate. So you need to treat the 100% figure as asymptotic - always approaching it, but never getting there. The details are beyond the scope of this pattern, but what you need is a formula which transforms time so far into a value that starts at 0 and approaches 100. An additional constraint is that it must fit with your estimate, so you might perhaps ensure your estimate is reached at the 80% point, allowing room for the progress meter to grow past it if the transfer takes longer. One last thing: no matter what the figure ends up at, be sure to drive it up to 100% at the end, to maintain the illusion that this is a real progress meter.

Another way to deal with long XMLHttpRequest Calls is to explicitly 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 1000 records, running a transformation on each of those and saving it to the database. The loop variable can be exposed so that a monitoring service can convert it into a percentage remaining figure.

Not all Progress Indicators concern a single XMLHttpRequest Call. Indeed, those requiring a progress meter are longer processes, likely incorporating several XMLHttpRequest Calls. There, you do have much better scope for real-time progress monitoring - each time a call returns, further progress has occurred. In a simple model, you can show progress is 50% complete when 2 of 4 calls have returned.


Real-World Examples

Amazon Diamond Search

Amazon Diamond Search is a Live Search that shows a Progress Indicator while updating the number of results. The indicator is a simple animation depicting a block moving back and forth with a "LOADING RESULTS" message. A 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.

Amazon Zuggest

Like Amazon Diamond Search, Francis Shanahan's Amazon Zuggest is a Live Search that shows a Progress Indicator while searching is underway. This time, 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!".

Protopage

Protopage is an Ajaxian portal. Each time you make a change, such as Drag-And-Drop a Portlet, an opaque "Saving ..." message appears in the bottom-right corner. This is a good model for a Fat Client application, where server synchronisation should be unobtrusive.

TalkDigger

TalkDigger 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 situation.

Kayak

Kayak illustrates how to handle a longer delay. When you search for a trip, it creates a result page with several forms of progress feedback:

  • Number of search results so far.
  • A progress meter that fills up from left to right.
  • A sampling of websites that are being searched.
  • A nice graphic depicting a pre-electronic airport display board. Initially, each character is random. As the search of a particular website proceeds, the random characters are replaced with the correct character for that website. Meanwhile, the characters that remain random continue to flip from one random character to another. Once all characters have been corrected and the website name displays correctly, the display changes to random again and starts revealing another website. all This is an excellent example of a graphic that is engaging and at the same time relevant to what's happening.

The Pick'em Game

The Pick'em Game 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.)


Refactoring Illustration

Sum Demo

This demo introduces a progress display to the Basic Sum Demo. It's a simple animated GIF that shows up while waiting for the sum to return.

To the initial HTML, an Img tag has been added to include the animation, initially hidden by the corresponding script.

  <img id="progress" src="progress.gif" />

  window.onload = function() {
    $("progress").style.visibility = "hidden";
    ...
  }

Now all we have to do is show the animation upon submitting and hide it when the result is in.

 function submitSum() {
   $("progress").style.visibility = "visible";
   ...
 }

 function onSumResponse(text, headers, callingContext) {
   $("progress").style.visibility = "hidden";
   ...
 }


Related Patterns

Status Area

A Progress Indicator is usually presented as a Status Area.

Popup

The Progress Indicator can sometimes reside in a Popup.

One-Second Spotlight

Once a long process has completed, use a One-Second Spotlight to point this out to the user.

Guesstimate

Sometimes 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 of the progress.

Distributed Events

When 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.


Visual Metaphor

Banks and post offices often use ticket-based queueing systems, showing the number that's currently being served.


Want to Know More?

Gnome Guidelines, Chapter 7: Feedback

AskTog.com First Principles of Interaction Design, Latency Reduction

[1] Public domain Progress Indicator icons.

[2] See Chapter 6 of Designing and Engineering Time: The Psychology of Time Perception in Software by Steven C Seow

Progress Indicator Generator Creates a custom progress indicator for download based on your stylistic preferences

Activity Indicators Contains a collection of progress indicators for download from different contributors