1. Home
  2. :
  3. Tests by component
  4. :
  5. Loading Feedback Patterns

Loading Feedback Patterns

Introduction

Every page, component, and container on the web has the potential to take a long time to load. This may be because of a user issue such as slow internet provider, a server issue at the server location, or any number of things that go wrong in between from severed underwater cables to overloaded routers.

If a user sits in front of a page that’s loading, but the page doesn’t communicate to the user that it’s still in a loading state, the user doesn’t know whether the page is intentionally empty, loading, or broken. The loading patterns, along with the empty state pattern, solve this problem by providing feedback to the user.

Why this is important

The user needs to know whether they’re wasting their time waiting for a page to load or whether everything is already present. Loading indicators provide that indication.

The Doherty Threshold: Productivity soars when a computer and its users interact at a pace (<400ms) that ensures that neither has to wait on the other.

– Walter J. Doherty and Ahrvid J. Thadani

Use when

The user needs to know whether the page or a portion of the page is still loading.

  • Ideally, every page loads in 200ms. (We choose half the Doherty Threshold because that gives us some leeway if loading for our users is twice as long as it took to load locally.)
  • If the page takes more than 200ms but less than 1 second, no loading indicator is needed.
  • If the page takes 1 second but less than 10 seconds, use the skeleton or loading spinner patterns.
    • Skeleton for full page or very large sections of pages.
    • Loading spinner for smaller page sections.
  • If the page consistently takes more than 10 seconds to load, use the progress bar patterns.
  • If the page takes more than 30 seconds to load, ensure that the people in charge of your team know that there are performance concerns on the page.
  • Worst case scenario is that the connection consistently times out or the volume of data crashes the user’s browser – we consider both of these cases total user experience failure and they should be avoided.

Do not use when…

  • All content loads consistently in less than one second. 
  • A specific piece of content has no data. Display an empty state instead. 

Only one loading indicator should display on the page at a time. If multiple components are slow to load, use the page loading pattern, not the component loading pattern.

Components Involved

  • Loading spinner
  • Skeleton
  • Progress bar

How to use

A note on screen reader prompts

By using an aria-live region or a component with role="status" the developer can prompt the screen reader to politely announce the state of some or all of the page.

You can achieve this by creating an element with role="status" which needs to remain on the page even after the loading indicator is not being rendered. When you use an element with role="status", screen readers will announce any changes of its content. Please view example in loading spinner for futher guidance. You should also set the hidden text to be empty after 5 second after it announces that things are loading to prevent any screenreader on browser mode from arrowing into the element.

The prompts provided are rough scripts to give you an idea of what needs to be communicated. They are descriptive, not prescriptive. Work with your UX Designer or UX Writer for exact wording.

If you are aware that a particular area of the page is going to take an exorbitantly long amount of time to load, like 30 seconds, the screen reader should read out the state of the progress bar multiple times as it is loading (say at 25%, 50%, 75%, and completion) so that the user continues to receive status updates. Hopefully this never happens, and for shorter durations announcing the beginning and ending of the loading state should be sufficient.

A note on animation shut-off switches

If we do not offer the ability to disable animation, we could cause the user physical harm such as vomiting, dizziness, migraines, or even seizures.

Best practice requires including a switch for the user to disable the animation. 

  • For full-page animations I recommend placing it in the top left corner of the page where the user is most likely to quickly find it. (Full page animations are more dangerous than partial page animations, in general.)
  • For partial-page animations I recommend placing it below the section head that notifies the user that the content is still loading.

Best practice is to provide a system-wide user setting for animation, and if that is available, it should be respected.

Similarly, if a user has turned on “Reduce Motion” in their operating system, you should use the prefers-reduced-motion CSS media feature to prevent or significantly diminish any displayed animation.

A note on empty states together with loading states

It can be tempting to make the empty state of a page the first thing that displays, and then pop in the content as soon as it loads, especially if it’s assumed that the content will load quickly.

Avoid this temptation. 

If you’re wrong about how long it takes for the content to load (and you will be wrong eventually, because you can’t predict the internet’s overall traffic) then what the user will experience is visible “no data” message followed by data. Not only does the initial “no data” message give the user reason to believe we lost their stuff, the subsequent loading of their stuff gives the user reason to believe we have no idea what we’re doing.

Full page loading – under 10 seconds

For full-page loading, a skeleton is preferable to a spinning loading indicator because the skeleton gives the impression of both the shape and volume of the content loading, which makes it easier for the user to understand why it’s taking so long.

The following example illustrates a page loading. 

  • For the point between 0 and 1 second, the page and navigation load blank
    • screen reader prompt: none
  • From 1 second to 8 seconds, the page continues to load, with an animated skeleton displaying for its contents.
    • screen reader prompt: This page is still loading.
    • We assume that the left navigation controls will not take more than 1 second to load, and they display as soon as they are available, with no skeleton involved.
  • At about the 8 second mark, the content has loaded and the skeleton disappears.
    • screen reader prompt: Loading is complete.

The following example illustrates the same page loading, but the user chooses to disable animation. Screen reader prompts are the same as above.

  • For the point between 0 and 1 second, the page and navigation load blank.
  • From 1 second to 8 seconds, the page continues to load. At around the 2 second mark, the user chooses to toggle the animation of the skeleton off.
  • The page continues to load until about the 8 second mark, with the non-animated skeleton displaying.
  • At about the 8 second mark, the content has loaded and the skeleton disappears. 

Full page loading – over 10 seconds

If the team knows that a specific page will take more than 10 seconds to load, the skeleton should be replaced with a status bar indicating the loading progress. Studies by Nielsen/Norman show that over 10 seconds users are uncomfortably aware that the content hasn’t yet displayed and want a better gauge of how long they’ll be waiting for loading to complete. A status bar is the best way to provide this guidance.

The following example illustrates a page loading. 

  • Almost immediately, the page and navigation load a message that the page is loading. (Note that for aria-live purposes this is almost immediately; the page needs to come in blank and then change to the loading state for the loading state announcement to happen.)
    • Screen reader prompt: This page is still loading.
  • From the time the loading message appears until all of the content has loaded in the background (approximately 13 seconds) a progress component displays the loading progress.
    • We assume that the left navigation controls will not take more than 1 second to load, and they display as soon as they are available.
  • When loading has completed, a 500ms pause allows the user to observe that loading is complete, then the loading information disappears and the content displays.
  • screen reader prompt: Loading is complete.

The following example illustrates the same page loading, but the user chooses to disable animation. Screen reader prompts are the same as above.

  • Almost immediately, the page and navigation load a message that the page is loading. (Note that for aria-live purposes this is almost immediately; the page needs to come in blank and then change to the loading state for the loading state announcement to happen.)
  • From the time the loading message appears until the user shuts off animation, the progress component displays.
  • When the user disables the animation, the progress component is hidden. 
  • When loading has completed, the loading information disappears and the content displays.

Partial page loading – under 10 seconds

If only one portion of the page is expected to load slowly, that portion of the page should be placed behind a scrim or other content area and marked as loading separately. Some components, such as tables, may provide a loading state. For others, you must design the behavior.

The following example illustrates a chart embedded in a page loading. 

  • All of the page content except the chart has loaded. 
  • The chart area loads a message that the content is loading. (Note that for aria-live purposes this is almost immediately; the specified area needs to come in blank and then change to the loading state for the loading state announcement to happen.)
    • Screen reader prompt: [name of area] is still loading.
  • After that point, the chart continues to load, with an animated loading spinner displaying for its contents.
  • At about the 4 second mark, the content has loaded and the spinner disappears.
    • Screen reader prompt: [name of area] is loaded.

The following example illustrates the same page loading, but the user chooses to disable animation. Screen reader prompts are the same as above.

  • All of the page content except the chart has loaded. 
  • Just like above, the chart area loads a message that the content is loading. 
  • From the time the loading message appears until the user shuts off animation, the loading spinner displays.
  • When the user disables the animation, the loading spinner is hidden. 
  • When loading has completed, the loading information disappears and the content displays.

Partial page loading – more than 10 seconds

Like the examples above, a component that will consistently take more than 10 seconds to load should display a progress bar to illustrate its progress. Some components, such as tables, may provide a loading state. For others, you must design the behavior.

The following example illustrates a chart embedded in a page loading. 

  • All of the page content except the chart has loaded. 
  • The chart area loads a progress bar indicating how far the content has loaded. (Note that for aria-live purposes this is almost immediately; the specified area needs to come in blank and then change to the loading state for the loading state announcement to happen.)
    • Screen reader prompt: [name of area] is still loading.
  • After that point, the chart continues to load, with the progress bar updating with the status of the loading information.
  • At about the 13 second mark, the content has loaded and the progress bar displays a 100% indicator, then disappears.
    • Screen reader prompt: [name of area] is loaded.

The following example illustrates the same page loading, but the user chooses to disable animation. Screen reader prompts are the same as above.

  • All of the page content except the chart has loaded. 
  • Just like above, the chart area loads a message that the content is loading. 
  • From the time the loading message appears until the user shuts off animation, the progress bar displays.
  • When the user disables the animation, the progress bar is hidden. 
  • When loading has completed, the loading information disappears and the content displays.

Form submission

Scenario: the user is submitting a form that takes a few seconds to send/receive, and double-clicking the “submit” button would cause a double-submission error. The designer has two options:

Loading time under 10 seconds and new page loading

  • For the point between 0 and 1 second, do nothing. 
  • At 1 second, pop a modal that contains a loading message and the loading spinner.
    • screen reader prompt: This page is still loading.
  • When the content is ready for the other page, close the modal and move the user to the new location.
    • Note that this pattern can also be used if the server returns an error, because you close the modal and return them to the form in an error state.
    • screen reader prompt: Loading is complete.

Loading time 10 seconds or more and new page loading

  • For the point between 0 and 1 second, do nothing. 
  • At 1 second, pop a modal that contains a loading message and the progress indicator.
    • screen reader prompt: This page is still loading.
  • When the content is ready for the other page, jump the progress indicator to 100%, close the modal and move the user to the new location.
    • Note that this pattern can also be used if the server returns an error, because you close the modal and return them to the form in an error state.
    • screen reader prompt: Loading is complete.

Any loading time and current page will reload with updated content

This is a scenario where the page is essentially a calculator and the results will be displayed with the same content, but updated data. In these cases, use the Full Page Loading examples above.

Accessibility Guidelines

The following Web Content Accessibility Guidelines impact this component:

Additional resources