Performance Is Design

Speed is something people feel before they measure it. Two apps can fetch the same data in the same time and one will feel quick while the other feels like it is thinking about it. The difference is what you show while the wait happens.

That makes waiting a design problem. Perceived performance is the part of speed you control with pixels, and it is usually the cheaper part to improve.

Press the button below. Both cards take the same 1.2 seconds to load.

  • Design reviewToday
  • Ship OG imagesYesterday
  • Fix Safari overscrollMonday
Spinner
  • Design reviewToday
  • Ship OG imagesYesterday
  • Fix Safari overscrollMonday
Skeleton

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

Short waits want silence

Loading states have a cost of their own. Every placeholder is a thing that appears and then disappears, and quick flashes of UI read as churn.

For a wait that ends in a blink, the calmest thing you can do is hold the layout and show nothing. Then fade the real content in.

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

A rough guide that has held up well:

  • Under about 300ms, show nothing. Reserve the space so nothing jumps.
  • Between 300ms and a second, hold layout and fade content in. A skeleton is fine if the wait is reliably in the upper half of that range.
  • Over a second, you owe people an explanation. This is where skeletons, progress, and honest copy belong.

Never stretch a loading state to make it "smooth". If the data is ready, show it.

Do not wait for permission

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

Wrong
Waits for the server
Right
Updates right away

This is what makes Linear and Things feel instant. Nothing about their network is special. They just stopped making you watch the round trip.

Even the spinner has a speed

When you really do need a spinner, how fast it turns changes how long the wait feels. Same load, two spinners.

1.6s per turn
0.5s per turn

The faster one is not lying. It is just not adding its own slowness on top of the real one.

The real fix

Shu Ding's point is that slow products rarely have one cause. They are hundreds of small decisions, each defensible, that nobody looked at together. Design is the act of looking at them together.

So the best loading state is often 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 do, which is to just show the thing.

Resources

Search concepts

Search for a command to run...