CLS: reserve the space
React chapter 144 · Web Perf · Core Web Vitals · layout shift, skeletons, aspect-ratio · source: Nadia Makarevich, Web Performance Fundamentals, Chapter 2 (Core Web Vitals); web.dev/articles/cls
The problem
A promo banner arrives a second after the article and is inserted above the buttons with no space reserved. Everything below jumps down just as the user aims for “Confirm”. That jump is a layout shift; CLS adds them up.
The pattern that fixes it
Reserve the final size before the content arrives: width/height on images (the browser derives aspect-ratio), a skeleton with the same box, or min-height on the slot. Content then fills a hole instead of pushing its neighbours.
In plain words
Things on the page should not move by themselves. If something is going to appear later, leave an empty box of the right size for it now.
Reserving a seat at the cinema with your jacket. When your friend arrives, nobody in the row has to shuffle along.
Terms
- layout shift
- A visible element changes position between two frames without the user causing it.
- CLS
- Cumulative Layout Shift. Good ≤ 0.1, poor > 0.25. Unitless.
- shift score
- impact fraction × distance fraction: how much of the viewport moved × how far it moved.
Going deeper
How the score is computed
Impact fraction: the union of the element’s old and new boxes, as a share of the viewport. Distance fraction: how far it moved, divided by the viewport’s larger side. A block covering half the screen moving 10% of the height scores about 0.5 × 0.1 = 0.05. Since 2021, CLS is the worst “session window” — shifts less than 1 s apart, capped at 5 s — not the sum over the page’s whole life.
Shifts the user asked for do not count
A shift within 500 ms of a click, tap or key press has hadRecentInput: true and is excluded. Opening an accordion is fine. A banner that lands 1.2 s after load is not. That is why this lab loads the banner on a timer, not in the click handler.
Usual suspects in React apps
Images without dimensions; ads and embeds; a cookie bar inserted at the top; a Suspense fallback smaller than the content that replaces it (chapter 147 — make the skeleton the real size); web fonts swapping metrics (use size-adjust or font-display: optional); client-only content that SSR rendered empty. Animate with transform — it does not move layout, so it never counts.
Keep learning
- Previous: Where LCP time goes
- Next: INP: the three parts of a click
- Related: lazy + preload
- Related: Request waterfalls
- Related: Yield to main
- Related: CSR blank vs SSR
- Related: React Compiler
- Related: Where LCP time goes
More courses
- Jobs, linked to lessons — Browse jobs where every requirement links to the chapter that teaches it. See how ready you are, how long the gap takes to close, and which listings look stale.
- Match a job post to courses — Paste a job post. Each skill is matched to a track here and put in learning order, foundations first.
- Database in depth — How a query becomes work. Indexes, isolation, locks, and the plans that explain why a page is slow — not an ORM tour.
- System Design — Eight interview case studies, from a flash sale and Tatkal to a live final and a chat model, plus JWT in separate chapters.
- Microservices — Microservice patterns one diagram at a time: how to split a monolith, how services talk, and how data stays consistent without distributed transactions.
- Kafka — A beginner-to-senior path through event logs, reliable delivery, production operations, and disaster recovery.
- Frontend system design — How a UI is sliced when it is a product, not a page: ownership of state, cache, routes, and what happens when the network lies.
- CSS in depth — See the box, then the page. Visual chapters from the box model through Flexbox surprises, Grid, selectors, and units, then backgrounds, shapes, and visual effects, each with a playground.
- Accessibility — HTML labs first, then a full pass of WAI-ARIA 1.3: naming, every state, widget and structure roles, live regions, ariaNotify, and relationships.
- Docker — What an image is, why layers cache, and how containers find each other on a network.
- Redis — Fifteen Redis patterns, one picture each: cache, session, lock, counter, rate limiter, queue, and when Redis is the wrong tool.