A spinner tells users "something is happening" but gives zero information about what or how long. That uncertainty is what makes waits feel slow.
Skeleton screens preview the shape of the incoming content — avatar circle, text bars, image block — so the brain starts parsing the layout before the data arrives.
The shimmer sweep matters: a static skeleton reads as "broken", an animated one reads as "in progress".
Match the skeleton to the real content dimensions. A skeleton that jumps to a different layout on load is worse than a spinner.
For actions the user just performed (posting, liking), skip loading states entirely — render the result optimistically and reconcile in the background.
Do / Don't
Do: shape skeletons to mirror the final layout, animate them, and keep them under ~2 seconds before showing partial content.
Don't: use skeletons for sub-300ms loads (flash of skeleton is noise) or mix spinners and skeletons in the same view.
The Design System Blueprint
An 11-page visual guide to consistent, scalable UI: colors, typography, spacing, components, motion.