A skeleton that does not match real structure produces a jump
Aliases: broken skeleton promise · wait-end jump · skeleton-to-content jump
What it is
Choosing a skeleton issues a spatial cheque during the wait: these slots, in these relative positions, in roughly this count, will be honoured by real content. If row count, block height or the presence of a sidebar fail to match when the payload lands, the cheque bounces and the screen jumps on the wait’s last frame. The jump is not ugly drawing. It is the selection handing a map that will be voided to someone who is still waiting. A spinner never issues that cheque, so it cannot go bankrupt this way.
Why it happens
A skeleton turns a wait from empty into reserved. Once the reservation is seen, gaze and pointing organise around it: eyes rest on the coming title band, a thumb hovers where the first button will be. If content arrives in a different geometry, that organisation is scrapped. Orientation has to be paid again at the arrival instant, plus a correction that “the picture just now was false”. What the wait hoped to save by rehearsal is spat back on the closing frame, with a broken promise on top.
Mismatch is rarely random implementation noise. It is the selection treating an ideal state as predictable structure: always a cover image, always a three-line blurb, always a right rail. Live payloads omit the image, shrink the blurb to one line, or drop the rail with a permission check, and the reservation is a size class larger or smaller than the object. Average-case skeletons still jump on extremes; maximum-case skeletons collapse into a hole when content is short — also a jump. The issue is whether this wait honours the geometry it named, not whether the grey blocks are rounded.
Where it stops holding
A small type-size gap or an optional icon can jump below the threshold of a broken promise, especially if the main anchors (header, first row, primary button) still line up. What hurts is changing scroll position, shoving already-visible real content out of the viewport, or swapping the hit target under a pointer. Shoves from later chunks are a different group: those are several cheques being cashed over time, not one skeleton cheque bouncing on the last frame. When structure was never predictable, the jump is a symptom of the wrong wait language — drop back to an indeterminate indicator rather than making the skeleton more “elastic”. Animating the jump into a 200 ms slide still costs the coordinates people had already aimed at; bankruptcy just looks smoother.
Applying it
- Treat the skeleton as a contract. Draw only slots this wait can honour. Do not paint modules that appear or vanish with the data in order to look like a finished page.
- Under-promise: a fixed header plus a variable list should be “header + one hint row”, not ten rows that delete seven on arrival.
- When structure can fork (sidebar or not, empty state or not), delay the skeleton until the fork is known, or use an indeterminate indicator until then.
- How to check: overlay the skeleton frame with the first frame of real content. If main anchors miss, a visible button is pushed away, or three rows become a dozen, the cheque bounced — revert the selection; do not only tweak radii.
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.4 Skeletons reduce subjective wait estimates more than spinners · I2.01.5 An indicator on a very short load creates needless flicker · 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.07 Skeleton screens · I2.11 Progressive rendering · I2.03 Chunked loading
- Search terms:
skeleton mismatch·layout jump·spatial promise
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.4Skeletons reduce subjective wait estimates more than spinners
- I2.01.5An indicator on a very short load creates needless flicker
- 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