Give loaders a minimum time

Wait for the request and a short minimum, so loaders never flash.

Sam Selikoff@samselikoff
Ever felt confused at a carefully designed loading state that flashes too quickly? Use Promise.all to add a minimum artificial delay, without penalizing your user ๐Ÿ‘‡
Jul 3, 2023View on X โ†—
Network

Save with a spinner

Pick a speed, then press Save in each pane.

Spinner = request timeBad
Spinner shownโ€“
Spinner โ‰ฅ 500msGood
Spinner shownโ€“
const MIN = 500;
showSpinner();
await Promise.all([save(), sleep(MIN)]);   // never shorter than MIN
hideSpinner();

// Optional: show the spinner only after ~150ms, so a
// near-instant response never shows one at all.

Why it matters, pros and cons

Why it matters

A loader that flashes for 80ms reads as a glitch. A steady minimum reads as work done.

Pros

  • Promise.all adds the minimum without a timer to clean up or race.
  • Slow requests pay nothing: the wait is the longer of the two.
  • One constant to tune, and every loader in the app behaves the same.

Cons

  • Fast responses now feel slower than they are, by up to the minimum.
  • Loaders a person triggers over and over can start to feel sluggish.
  • Skip it when the result is the feedback, as with an instant toggle.