Loading States
What to show while waiting, chosen by how long the wait is and whether its length is known.
Definition
A loading state communicates that work is in progress. The right treatment depends on duration, on whether progress is measurable, and on whether the user can do anything else meanwhile.
Craft convention. True because the industry converged on it. Breaking it costs familiarity, not correctness.
On this plate
Reach for this when
- Any asynchronous operation.
- Optimising perceived performance.
- Data arrives slowly enough that the reader will notice, which is most of the time on a real network.
Common mistakes
- Spinners for sub-second waits.
- Skeletons that mismatch the content.
- No timeout or failure state.
- Loading state invisible to assistive technology.
Choosing the treatment
| Duration | Treatment |
|---|---|
| Under 300ms | Nothing. Delay any indicator so fast responses never show one. |
| 300ms to 1s | Subtle inline indicator, or an optimistic update. |
| 1s to 5s | Skeleton matching the final layout. |
| 5s to 30s | Determinate progress with a description of the current step. |
| Over 30s | Background job with a status surface and a notification when done. |
| Unknown duration | Indeterminate indicator plus a clear description of what is happening. |
Details that matter
- Delay the indicator by 200 to 400ms, then hold it for a minimum of about 500ms to prevent flicker.
- Skeletons should match the real layout, or the content shifts when it arrives and produces layout instability.
- Preserve scroll position when content loads in place.
- Announce loading and completion to assistive technology, since a visual spinner conveys nothing to a screen reader.
- Disable the triggering control while its operation is running, to prevent double submission.
- Always provide a failure path. A spinner that never resolves is the worst possible state.
Covering a wait
Do
- Acknowledge the input immediately, whatever else is still happening.
- Keep the indicator inside the region that is loading, so the rest stays usable.
- Reserve the space the content will occupy.
- Say what is happening for anything over a few seconds, and offer a way to leave.
Do not
- Show a spinner for something that resolves in under a second.
- Replace the whole screen for a change that affects one row.
- Show a skeleton that does not match the layout that arrives.
- Leave a failed request looking like one that is still loading.
Escalating as a wait gets longer
One operation can pass through several of these. Each step adds information rather than replacing what came before.
- 1
Acknowledge the input
Immediately, and before anything else: the control responds, so the reader knows the click registered.
- 2
Show the shape of what is coming
Past about a second, a skeleton in the exact layout of the result, so nothing moves when it arrives.
- 3
Name the current step
Past about five seconds, words beat a bar: Checking availability, then Reserving your seat.
- 4
Give an estimate or a proportion
Determinate progress where you honestly know the total. A fake bar that stalls at 90 percent costs more trust than no bar at all.
- 5
Move it to the background
Past about thirty seconds, release the screen, keep a status surface, and notify on completion.
- 6
Always have a failure branch
A timeout that resolves into an error with a retry. A spinner that never ends is the worst state in the product.
Treatment by how long the wait is
In practice
- i.
Skeletons that do not match
A common failureA three-line skeleton replaced by a single line of content shifts the layout on arrival, which is worse than showing nothing. The skeleton has to be built from the same layout as the content.
- ii.
The skeleton that lied
MismatchA skeleton showing three rows before content that arrived as one long block produced a visible jump and a moment of disorientation. A skeleton is a promise about the layout, and it has to be kept.
Commonly confused with
Close neighbours that get substituted for each other. The difference is stated first, then the condition that picks one over the other.
Empty States
PatternThe screen shown when there is genuinely nothing to display, by design or by result.
Key difference
An empty state is a finished request that returned nothing. A loading state is an unfinished request. They look identical if you let them, and they need opposite copy: one explains, the other reassures.
Use Loading States when
- The outcome is not known yet.
- You are choosing between a skeleton, a spinner and progress.
- The question is how long a wait can go unexplained.
Use Empty States when
- The request finished and the answer is zero.
- The reader needs to know why, and what to do next.
- A first-run screen is the strongest teaching moment you get.
Local chart
PAT·011 · Region III · Grid F1
This entry and the entries it is stated to connect with. Each line is labelled with what the connection means.
Continue from here
Each link says what the connection is, so you can tell a principle from an alternative from a thing people mix this up with.
Applies when you are designing
Principles behind this
The reasoning this solution is an application of.
- Visibility of System StatusHEUR·001 · Heuristic
- Doherty ThresholdLAW·006 · Law
- FeedbackPRIN·004 · Principle
- ImageryFND·051 · UI foundation
- MotionFND·052 · UI foundation
- Performance as User ExperienceFND·054 · UI foundation
Depends on
Get these right first, or this one will not hold.
- Status Messages and Live RegionsA11Y·009 · Accessibility
Often used with
These usually appear in the same screen or the same decision.
- ButtonCMP·001 · Component
- Progress IndicatorCMP·026 · Component
- Infinite Scroll and PaginationPAT·021 · Pattern
- Skeleton ScreensPAT·012 · Pattern
- WebPageTestTOOL·032 · Tool
Alternative approach
A different answer to the same problem, with a different cost.
- Optimistic UIPAT·013 · Pattern
Optimistic UI removes the wait instead of decorating it, and pays for it in rollback complexity.
Check your work
Review passes that test whether this was done properly.
- Dashboard UX ChecklistCHK·004 · Checklist
Short definition
The one-paragraph version, for when that is all you need.
- Core Web VitalsTERM·123 · Term
- Empty StateTERM·050 · Term
- Graceful DegradationTERM·121 · Term
- Live RegionTERM·079 · Term
- Optimistic UITERM·051 · Term
- Skeleton ScreenTERM·047 · Term
- StateTERM·036 · Term
Related concept
Connected closely enough to change how you apply this.
- Empty State CopyWRT·010 · UX writing
- Loading and Progress CopyWRT·011 · UX writing
- User FlowsFLOW·009 · Workflow