An indicator on a very short load creates needless flicker
Aliases: wait flash · premature wait chrome · sub-threshold wait presentation
What it is
Skeleton versus spinner is a choice made after the UI has entered a wait presentation. If the load finishes inside the window where the act still counts as “happening”, neither treatment should appear. Appear-and-vanish is a meaningless state flash: flicker. Flicker is not honesty. It rewrites a completed action as a wait and then cancels the wait. The first cut in wait strategy is not which chrome to use. It is whether this interval is long enough to be presented as a wait at all.
How a spinner component delays its entrance, and how long it must stay once shown, belongs to the indicator group. This leaf is the policy: requests that die under the threshold never switch into wait presentation.
Why it happens
People keep a short stretch after an act in which it still counts as the same event. The screen may sit still in that stretch without breaking the bind. Insert a skeleton or a spinner and the same clock time is recoded as “I am waiting on the system” — the recoding itself is a state change. If the request finishes on this frame or the next, what is seen is press → wait skin → done, three beats with no information in the middle, only an attention-grabbing on/off. Flicker steals gaze and leaves the impression that the system is busier than it was, so people tap again or rate the product as unstable.
The threshold is not taste. Local filters, cache hits and an already-prefetched next page often fall inside the window; cold network requests often fall outside. A policy of “any request enters wait presentation” forces a large set of waits that never needed to be shown. A skeleton is not more innocent here than a spinner: a one-frame grey page is louder than a small spinner because it rewrites more pixels.
Studying it
Inject controlled delay after the same action and compare “enter wait presentation as soon as the request leaves” with “enter only after a threshold”. The critical contrast is objectively short time with wait skin that nevertheless flashes.
Independent variables: delay length, kind of wait skin (skeleton / spinner / none), whether the control already has an immediate pressed state. Dependent variables: reports of “it hitched”, repeat clicks, remembering a completed act as slower, rated instability.
Do not treat “did they see the indicator” as success. Seeing it on a short delay is the failure: people were trained to monitor a wait that did not exist. Lab participants who know they are in a loading study tolerate a flash more than product users; in products the flash stacks with pressed states and route transitions, so those immediate confirmations must be stripped out of “wait presentation” before the comparison.
Where it stops holding
If a button has no pressed state at all, people need some other instant confirmation — that is feedback at the control, not a licence to enter wait presentation. When the act is already modelled as slow (export, payment, install), the threshold can sit lower, because the expectation is already a wait and a missing indicator is read as “the tap missed”. On a weak network, “usually fast” becomes “often slow”; a fixed threshold then makes wait presentation late, and people start double-tapping inside it. Pair that with re-entry protection rather than dropping the threshold to zero and flashing the fast requests again. The skeleton admission rule (predictable structure) does not override this leaf: even a perfectly known layout should not grey the whole page for a few tens of milliseconds.
Applying it
- Put a gate on entering wait presentation. Requests that finish under it keep the current screen; only the control’s instantaneous state may change.
- Split the gate by action type. Local filtering can wait longer before admitting a wait; a cold cross-network request can admit sooner.
- Put skeleton and spinner through the same gate. Do not delay the spinner and flash the skeleton immediately. A one-frame full-page skeleton is the heavier flicker.
- How to check: on a fast network or cache hits, perform common actions in a row and inspect frame by frame for a single-frame wait skin. If it is there, raise the enter-wait delay until those fast requests are covered.
Related
- Same group: I2.01.1 Use a skeleton when the forthcoming structure is predictable · I2.01.2 When structure cannot be predicted, use an indeterminate indicator · I2.01.3 A skeleton that does not match real structure produces a jump · I2.01.4 Skeletons reduce subjective wait estimates more than spinners · I2.01.6 A spinner carries no progress and, used for long, is read as frozen · I2.01.7 Skeleton motion needs one shared cadence; mixed breathing looks cheap
- Nearby: E6.08 Loading indicators · I1.01 Instantaneity threshold · I1.02 Continuity-of-thought threshold
- Search terms:
indicator flicker·deferred wait presentation·short-load flash
Cards in the same group
- I2.01.1Use a skeleton when the forthcoming structure is predictable
- I2.01.2When structure cannot be predicted, use an indeterminate indicator
- I2.01.3A skeleton that does not match real structure produces a jump
- I2.01.4Skeletons reduce subjective wait estimates more than spinners
- I2.01.6A spinner carries no progress and, used for long, is read as frozen
- I2.01.7Skeleton motion needs one shared cadence; mixed breathing looks cheap