The honest skeleton
A skeleton that promises a shape the answer may never take is a lie the UI tells for the whole duration of the wait — and the fix is usually fewer placeholders, not smoother ones.
The previous three lessons have all ended by leaving a hole. Hold the points cost until it settles: a hole. Hold the fenced block until it closes: a hole. Hold the second recommendation until its array element exists: a hole, card-shaped, that you were about to fill with a grey rectangle that looks like a card.
That grey rectangle is a claim. It says a card is coming, that it will be about this tall, that there will be this many of them, and that they will contain a row here and a price there. On the flight chatbot, most of those are guesses, and one of them is routinely false: the answer to a hard award question is sometimes one option, sometimes three, and sometimes “there is no award space at your dates, here is what to do instead.” A skeleton of three cards, drawn over that answer, spends the entire wait promising a comparison that never arrives.
The band, and where your surface sits in it
NN/g’s own guidance for skeletons is a three-part scale. “If a page takes less than 1 second to load, skeleton screens or spinners aren’t necessary”; “skeleton screens should be used with a wait time that’s under 10 seconds”; and past ten seconds the article recommends a progress bar instead. NN/g sells UX consulting and training, which is worth naming every time this course cites them, and this is still the primary text rather than a summary of one.
Read that against your measured baseline. A hard award question takes tens of seconds. Your surface is not in the band this article is written for — it is past the top of it, in the region where NN/g recommends the one instrument you cannot build, because a percent-done indicator needs a denominator and an agent has no honest one. That was the argument of the first lesson in this course, and it lands here as a practical conclusion: a skeleton is not your primary answer to the wait. Narration is. The skeleton is a local device for the holes inside an answer that is already arriving, and that is a much smaller job than the one it usually gets given.
What a skeleton may honestly promise
The rule is one line, and it is this course’s own framing rather than anything NN/g says in these words:
A placeholder may only describe a shape the response is guaranteed to contain.
Guaranteed, not likely. Run your own answer through it and the list collapses fast:
| Placeholder | Guaranteed? | Verdict |
|---|---|---|
| An answer region exists | Yes | Honest. Draw it. |
| A narration line while tools run | Yes, once the first step event arrives | Honest, and it is the real instrument |
| Three recommendation cards | No — may be one, may be none | Cut |
| A card with a price row | Only after the object has that element | Draw it then, not before |
| Three lines of text of decreasing width | No — the answer may be two words | Cut |
| A comparison table with four rows | No | Cut |
Notice what the fourth row does to the problem. Once the answer streams as a schema-shaped object, a card’s existence stops being a guess: the array element is there or it is not. You are not predicting a shape, you are rendering one that has arrived with its fields still filling in. The skeleton shrinks from “a drawing of the answer we expect” to “the parts of an arrived thing that have not landed yet,” which is a claim you can actually back.
That is what “fewer placeholders, not smoother ones” means concretely. The instinct when a skeleton feels wrong is to soften it — slower shimmer, gentler contrast, a crossfade into the real content. None of that changes what it promised. Deleting the two rows you cannot vouch for does.
NN/g’s own criticisms, and where this course goes further
The article is more measured than this lesson is, and the difference is worth keeping visible. Its own complaint about a structure-only skeleton is that such screens “fail to communicate page structure accurately”. It warns that animated skeletons “can potentially be distracting, annoying, or even create accessibility problems”, and that a skeleton flashed too briefly “can cause users to feel like they can’t keep up”.
Calling an inaccurate skeleton a lie the UI tells is this course’s language, not NN/g’s, and it is deliberately stronger than theirs. The reason for the escalation is specific to this surface: on a page load, an inaccurate skeleton is corrected in under a second and the user barely registers it. On a forty-second agentic answer, the same inaccuracy is on screen for forty seconds, and it is the only thing on screen. Duration is what turns an inaccuracy into an assertion. If you disagree with the escalation, disagree with that argument — it is the course’s, not a citation.
Where the article is bluntest is the part most often skipped: skeletons “do not replace performance-optimization efforts” and are “simply one extra tool.” Translated to this course: a skeleton does not substitute for streaming, for narration, or for the per-component disclosure decisions the module opened with. It is what you put in a hole after you have justified the hole.
Where people get burned
The specific way this ships wrong is a skeleton built from a design mock. The mock shows the best-case answer — three cards, a full table, a tidy paragraph — because that is what makes a good slide. Someone builds the loading state by taking that mock and greying it out, and the result promises the best case on every request including the ones that return one option or none.
The tell is easy to check: if your skeleton was derived from a rendering of a successful answer rather than from the schema and the stream’s own events, it is promising the mock. Delete the rows the schema does not guarantee.
Check your recall
Answer from memory — no scrolling back.
Retrieval check
Your skeleton is one grey rectangle in the answer region, no card outlines, no text lines. Someone calls it lazy. Defend it or fix it.
Check your answer
Defend it, with one condition. A single region is the largest shape you can guarantee before anything has arrived, so it is the honest maximum, and adding card outlines to it would be adding a promise rather than adding information. That is not laziness, it is the rule applied.
The condition is that it must not be the whole design. An undifferentiated rectangle for forty seconds is honest and useless — it carries no more information than the spinner this course started by rejecting. It earns its place only if it is replaced within a second or two by narration of the work in progress, and then by real components as the object’s fields arrive. The honest skeleton is small because something better takes over almost immediately. If nothing does, the problem is not the skeleton.
Hands on
Audit every placeholder against what the response guarantees
Done when: Every placeholder in the chatbot’s answer area is traceable to something the schema or the stream’s own events guarantee, the ones that are not have been deleted, and a run that returns zero recommendations never draws a card-shaped placeholder.
- Screenshot the current loading and mid-stream states. All of them, including the one that only appears between the submit and the first token. You are auditing what is on screen, not what you intended.
- For each placeholder element, write down the thing that guarantees it: a schema field, an arrived array element, a step event from the stream, or nothing. “The design mock” is nothing.
- Delete every element whose guarantee is nothing. Expect the answer area to get emptier and expect that to feel wrong. Sit with it, then check what fills the space instead: narration should, within a second or two.
- Rebuild the remaining placeholders so they are driven by arrival rather than by prediction. A card’s frame appears when that array element appears, not before; a price’s placeholder appears inside a card that exists.
- Force the zero-result answer — ask for award space on a date with none. The pass condition is that no card-shaped placeholder is ever drawn during that run. This is the case the design mock does not have and the one that proves the audit worked.
- Record in
ARTIFACT.md: each surviving placeholder and its guarantee, each deleted one, and what the zero-result run looks like from first token to final state. Bring the list into the chat. I will ask what guarantees each survivor and will not accept “it always returns at least one.”
What this does not cover
This closes the module on rendering a partial answer. You can now decide per component what may be shown before it is complete, stream structure so that decision is expressible, render arriving markdown without the answer area rewriting itself, and put something honest in the holes that leaves.
All of it assumes the stream finishes. It does not always, and the parts nobody demos come next: what a stop button actually stops and what state it leaves on both sides, what a retry does to an answer that is already half on screen, what survives a refresh and what infrastructure that costs, and how to correct an answer the user is already reading. That is the control module, opening with the stop-button lesson.
The rendering cost of everything in this module — a card re-rendering per field, a skeleton animating for forty seconds, an answer area reconciling on every chunk, and how you would measure any of it — belongs to Front-end performance under streaming load. There are no numbers in this module for a reason. That course owns the budgets and the profiling; this one owns what is allowed on screen and when.
Read this next — primary source
Skeleton Screens 101Nielsen Norman Group — free; NN/g sells UX consulting, training and research reports, so read it as an interested party publishing its own guidance. Fetched 2026-09-05
Read it for the band, and for the sentence teams skip. The band is the article’s own scale for when a skeleton is the right instrument at all — under a second, nothing; up to ten seconds, a skeleton; past that, something that reports progress — and it is a different scale from the response-time limits this course cited in its first lesson, which is worth seeing side by side rather than merged. The sentence teams skip is that skeletons do not replace performance work and are one extra tool, which is the whole argument of this lesson written by someone with no stake in your architecture.
Stuck, curious, or think this lesson is wrong? Ask your teaching agent. The lessons are the scaffold; the conversation is where the learning gets unstuck.