skip to content

In a loading-indicator spec, why add a short delay before a spinner appears and a minimum time it stays visible once shown?

level: middleimportance: should knowfreq 46%

answer

  1. fast responses and flicker
  2. a flash reads as a glitch
  3. the just-after-the-delay case
  4. cancel the timer on the fast path
  5. conventions, not mandated numbers

basics

~20 s

The delay keeps fast responses from flashing a spinner that reads as a glitch; the minimum display time stops a spinner that did appear from vanishing a split second later. Both remove flicker; neither slows fast responses.

solid answer

~40 s

Most requests in a well-built app finish quickly, and a spinner that appears for 80 ms is not feedback — it is a flicker that draws attention to a wait nobody noticed and makes the app feel slower. So the spec waits a short time, commonly a few hundred milliseconds, before showing the indicator, and cancels it if the response arrives first. That creates a second problem: a response that lands just *after* the delay makes the spinner appear and vanish. A **minimum display time**, commonly around half a second, keeps a shown indicator up long enough to be read. Both numbers are conventions tuned per product, not standards. The delay applies to the loading indicator, not to the immediate pressed feedback that tells the user their tap registered.

code

pseudocode · 16 lines
pseudocode
on requestStarted:
  shown = false
  delayTimer = schedule(SHOW_DELAY):
    showIndicator()
    shownAt = now()
    shown = true

on requestFinished(result):
  cancel(delayTimer)            // no effect if it already fired
  if not shown:
    render(result)              // fast path: indicator never appeared
  else:
    remaining = MIN_VISIBLE - (now() - shownAt)
    schedule(max(0, remaining)):
      hideIndicator()
      render(result)

go deeper

for a junior

Recall that very fast responses should not flash an indicator, and that a shown indicator should stay long enough to be seen.

for a middle

Explain how the delay and the minimum interact, including the fast path where the delay is cancelled and the minimum never applies.

for a senior

Tune the values from real latency data, keep pressed feedback immediate, and spot where the minimum is wrongly holding back fast results.

for a principal

Make timing a shared system value so every team's indicators behave the same, and weigh the latency the minimum adds against the flicker it removes.

## The problem both rules solve: flicker A **loading indicator** exists to reassure the user during a wait they would otherwise notice. When the wait is shorter than the user can perceive, showing an indicator does the opposite of its job: - A spinner that flashes for a fraction of a second reads as a **visual glitch**. - It **draws attention** to a wait the user would never have noticed. - It can make the product **feel slower** than one that simply shows the result. - On a screen with several independent regions, many brief flashes make the interface **look unstable**. Two timing rules, usually specified together, remove that flicker. ## Rule 1: a delay before showing The indicator is **scheduled**, not shown, when the request starts. If the response arrives before the delay elapses, the scheduled display is cancelled and the user sees only the result. Common practice puts this delay somewhere in the low hundreds of milliseconds — the band where a response still feels close to immediate. That number is a **convention**, justified by perception research on response-time limits, not a rule any standard mandates; teams tune it against their own latency distribution. ## Rule 2: a minimum display time once shown The delay creates an edge case. A response that arrives *just after* the delay makes the indicator appear and disappear almost at once — the same flicker, moved later. So once the indicator is visible, it stays for a **minimum duration**, commonly a few hundred milliseconds up to about half a second, long enough to be perceived as a deliberate state rather than a glitch. Again, a convention with a reason, not a mandate. ## How the two combine | Response time | Delay 300 ms, minimum 500 ms | What the user sees | |---|---|---| | 150 ms | Delay timer cancelled | Result only; no indicator ever | | 320 ms | Shown at 300 ms, held to 800 ms | Indicator for 500 ms, then result | | 2 s | Shown at 300 ms, hidden at 2 s | Indicator for 1.7 s, then result | The fast path is untouched: the minimum applies **only if the indicator actually appeared**. The cost is on the middle row, where the result is held back a few hundred milliseconds so the indicator does not flash. That is the trade-off teams accept deliberately, and why the minimum should stay short. ## What the rules do not replace - **Immediate acknowledgement of the tap.** The pressed or selected state of the control the user touched must still respond at once; the delay is for the *loading* indicator, not for all feedback. - **Skeletons on first load.** A screen with nothing to show yet usually renders its skeleton immediately, because an empty screen is itself a flash of wrongness. - **Progress bars on long, known work.** A minute-long export shows its progress right away; delaying it only hides useful information. ## Worked example: saving a workout note In a fitness-tracker companion app, saving an edited workout note usually completes in about 150 ms and occasionally takes two seconds on a weak connection. With a 300 ms delay and a 500 ms minimum, the common case shows no spinner at all, the slow case shows a steady spinner, and the awkward case — a response at 320 ms — shows the spinner for half a second instead of a 20 ms flash. The algorithm below is the component contract the spec describes; its guard is the cancelled timer on the fast path. ## Checklist for the spec 1. State the delay and the minimum as named timing values the whole system shares. 2. Say which indicators they apply to and which they do not. 3. Require that the minimum applies only when the indicator was shown. 4. Keep the pressed feedback on the triggering control immediate.

  • How would you pick the delay and minimum values for a specific product?
    Start from the conventional bands and the product's own latency distribution. If most responses land at 100-200 ms, a delay just above that hides the indicator for the common case. Keep the minimum short, because it adds latency whenever it applies. Then watch real sessions or recordings on slow connections to confirm there is no visible flicker in either direction.
  • Should a screen reader hear anything for a request that finishes inside the delay?
    No. If no indicator appeared, there was no perceptible wait, and announcing one would be noise. The waiting state is announced only when the indicator is actually shown; what matters then is that the end of the wait — the result or an error — is also conveyed.

saying these in an interview costs you the question

  • Show the spinner immediately so users always know something is happening
  • The minimum display time should apply to every request, even fast ones
  • A 300 ms delay is a WCAG requirement
  • Delaying the spinner means the tapped control shows no feedback either
  • A spinner that flashes for 50 ms is harmless