Loading State Patterns

Loading states provide feedback during asynchronous operations. Choose the right pattern based on operation duration, progress visibility, and user context.

When to Use Each Loading Pattern

PatternDurationProgressUse Case
SpinnerShort (under 2s)UnknownQuick API calls, saves
Linear ProgressMedium (2-10s)KnownFile uploads, multi-step forms
Circular ProgressMediumKnownBackground tasks, processing
Skeleton ScreenShort to MediumUnknownInitial page load, list loading
Progressive DisclosureLong (10s+)IncrementalDashboard, infinite scroll

Determinate Progress (Linear)

Use linear progress bars when you can track the exact progress of an operation. Show percentage and estimated time when possible.

File Upload

Multi-step Form Progress

Step 2 of 540% Complete

Budget details

Data Processing

Indeterminate Progress

Use indeterminate progress indicators when you cannot track exact progress or the operation is very quick.

Indeterminate Linear Progress

Inline Spinner (Button Loading State)

Section Loading

Loading budgets...

Skeleton Screens

Skeleton screens show the structure of the content before it loads, providing a smoother perceived loading experience.

List Item Skeleton

Card Skeleton

Table Skeleton

Progressive Disclosure

Load content incrementally to show partial results quickly rather than blocking the entire page.

Dashboard Loading (Incremental)

Recent Transactions

  • Coffee - 4.50 EUR
  • Groceries - 45.20 EUR
  • Transport - 12.00 EUR

Loading budgets...

Infinite Scroll Loading

Transaction 1

Details for transaction 1

Transaction 2

Details for transaction 2

Transaction 3

Details for transaction 3

Loading more...

Optimistic UI Updates

Show the expected result immediately while the operation completes in the background. Revert on error.

Optimistic Like/Favorite

Budget: Groceries 2024

Clicking "Favorite" immediately shows the filled star while saving in background

Best Practice

Timeout Handling

For long-running operations, provide feedback and allow users to cancel or take alternative actions.

Long Operation with Cancel

Timeout with Retry

Usage Guidelines

When to use

  • Show loading feedback for operations over 1 second
  • Use determinate progress when you can track exact progress
  • Use skeleton screens for initial page loads
  • Use progressive disclosure for dashboard or list loading
  • Use optimistic UI updates for user-triggered actions

Best practices

  • Provide cancel options for operations over 10 seconds
  • Load content progressively rather than blocking entire page
  • Disable buttons during loading to prevent duplicate submissions
  • Show descriptive text with loading indicators
  • Use indeterminate progress for operations under 2 seconds
  • Avoid spinners for operations under 300ms

Accessibility

  • Loading states announced with aria-live="polite"
  • Progress bars use role="progressbar" with aria-valuenow
  • Loading spinners have aria-label describing the operation
  • Buttons indicate loading state with aria-busy="true"
  • Keyboard users can cancel long operations with Escape key
  • Loading indicators meet WCAG AA contrast requirements

Do's and Don'ts

Do

  • Show loading feedback for operations over 1 second
  • Use determinate progress when possible (with percentage)
  • Provide cancel options for long operations
  • Use skeleton screens for initial page loads

Uploading budget-report.pdf - 45% complete

Don't

  • Use generic "Loading..." without context
  • Block the entire UI for partial updates
  • Use spinners for operations under 300ms
  • Show loading indicators without descriptive text

Loading...

Performance Considerations

Timing Guidelines

  • Under 100ms:No loading indicator needed - feels instant
  • 100-300ms:Optional subtle indicator (e.g., button state change)
  • 300ms-1s:Show spinner or indeterminate progress
  • 1-10s:Show determinate progress if possible, with context
  • Over 10s:Provide cancel option and consider background processing

Related Components

Resources