Skip to content

Performance Is Design

Two apps can fetch the same data in the same time, and one will still feel faster. The difference is what each one shows you while you wait.

What you show during a wait decides how long it feels. That makes waiting a design problem, and usually a cheaper one to fix than the network.

Press load. Both cards take the same 1.2 seconds.

  • Design reviewToday
  • Ship OG imagesMon
  • Fix Safari overscrollFri
Spinner
  • Design reviewToday
  • Ship OG imagesMon
  • Fix Safari overscrollFri
Skeleton

The spinner says "please wait". The skeleton shows the shape of what is coming, so your eye already has somewhere to go. Same wait, and the second one feels shorter.

Match the wait

Jakob Nielsen's response time limits are still the best guide:

  • Under 100ms feels instant. Just show the result.
  • Under 1 second, people notice the delay but keep their train of thought. Show nothing, and hold the space so the layout does not jump.
  • Past 1 second, show that something is happening, with a skeleton or a spinner.
  • Past 10 seconds, show progress and an estimate.

The second row is the one people get wrong. A skeleton that lives for 300ms is not reassurance. It is a flash.

Wrong
  • Design reviewToday
  • Ship OG imagesMon
  • Fix Safari overscrollFri
Skeleton for 300ms
Right
  • Design reviewToday
  • Ship OG imagesMon
  • Fix Safari overscrollFri
Nothing, then fade in

Don't make people watch the round trip

Most actions succeed. When you already know what the result will look like, show it right away and let the request catch up. If it fails, roll it back and say so.

Wrong
Waits 700ms
Right
Updates at once

The left list is honest about the network. The right one is honest about the outcome, which is the part people care about. React ships this pattern as useOptimistic.

Even the spinner has a speed

When a spinner is the right call, how fast it turns matters. As Emil Kowalski points out, a faster spinner makes the same load feel quicker.

Slow
1.6s per turn
Fast
0.5s per turn

The best loading state

None of this replaces being fast. The best loading state is the one you deleted: cache the data, render it on the server, prefetch on hover. Then the interface gets to do the most confident thing it can, which is to just show the thing.

Resources

Search concepts

Search for a command to run...