Back to notes

Essays

Loading states are where a product tells the truth

A spinner often means the interface has avoided saying what is really happening.

UXPerformanceState Management

I care more about loading states than most people expect. Not because skeletons are exciting, but because waiting is where the product either builds trust or quietly spends it.

A spinner is sometimes fine. More often, it is a confession that the interface has not decided what the user deserves to know. Are we fetching data? Creating something? Waiting for an AI response? Rechecking permissions? Saving work that can fail? Those are different experiences, and the UI should not flatten them into one vague circle.

Good loading states preserve the shape of the screen, protect users from accidental double actions, and make progress feel explainable. They also tell engineers whether the data flow is well designed. If the UI cannot represent the in-between state cleanly, the architecture probably cannot either.

This is especially true in complex SaaS products. The user is often trying to keep context in their head: filters, selected rows, unsaved changes, a pending recommendation, an action they are not sure they can reverse. A lazy loading state can make them feel like the product forgot what they were doing.

I like loading behavior to be part of the feature model, not a decoration added in the last pass. Pending, refreshing, saving, retrying, blocked, partial, and stale are product states. They should be named, tested, and designed as seriously as success.

Performance is not only milliseconds. It is also orientation. A slower system that explains itself can feel more trustworthy than a faster system that jumps, blanks out, or hides the consequence of an action.

When I review a product surface, loading states are one of the first places I look. They reveal whether the team has designed for reality or only for the happy path.