Largest Contentful Paint (LCP) & Cumulative Layout Shift (CLS) Sub-Metrics
- Last updated
- Prerequisites:
- Critical rendering path
- Browser layout engine fundamentals
- browser
- web-vitals
- lcp
- cls
- performance
- layout-shift
Read at your depth
The practical view
Largest Contentful Paint (LCP) tracks perceived load speed by measuring when the largest visible text block or image finishes rendering in the viewport (target <= 2.5s). Cumulative Layout Shift (CLS) measures visual stability by tracking unexpected element movements during the page lifecycle (target <= 0.1). LCP breaks down into Time to First Byte (TTFB), Resource Load Delay, Resource Load Duration, and Element Render Delay.
The same idea in other frameworks
`next/image` with `priority` for LCP; fixed aspect-ratio wrappers to eliminate CLS.`NgOptimizedImage` with `priority` attribute and mandatory `width`/`height`.`<NuxtImg preload>` with aspect-ratio CSS placeholders.SvelteKit `@sveltejs/enhanced-img` generating intrinsic aspect-ratio styles.Legacy vs modern
Lazy LCP Image & Unbounded Ad vs Preloaded LCP & Reserved Space
Late-discovered lazy images hurt LCP and unreserved dynamic banners cause CLS; preloading and aspect-ratio reservation solve both.
<img src="hero.jpg" loading="lazy" /> <!-- ❌ LCP delayed + CLS on inject --><link rel="preload" fetchpriority="high" ... /> <div style="min-height: 250px">...</div> <!-- ✅ NEW -->Interview gotchas
Context
Tests deep diagnostic knowledge of the Core Web Vitals breakdown.
The mechanical answer
The four sub-parts are: (1) TTFB (time until HTML arrives), (2) Resource Load Delay (time between HTML arriving and the browser initiating the image fetch), (3) Resource Load Duration (time to download image bytes), and (4) Element Render Delay (time from image download until it is painted). Resource Load Delay is often the easiest win: fixing it means eliminating client-side CSS/JS discovery chains via HTML `<link rel='preload'>` or `fetchpriority='high'` directly in initial HTML.
Trap
Never put `loading='lazy'` on an above-the-fold hero image; it introduces massive Resource Load Delay because the browser defers the fetch until after layout completes.
Context
Probes understanding of layout engine shift tracking vs compositor transformations.
The mechanical answer
The CLS algorithm specifically monitors shifts in *layout boxes* within the Layout Tree during layout reflow passes. Animating `transform` (`translateX/Y`) operates entirely on the Compositor thread by modifying layer matrices without changing the element's layout geometry box, resulting in a CLS score of 0. Animating `top`, `margin`, or `height` invalidates layout geometry on every frame, generating `LayoutShift` entries.
Trap
Do not claim that any smooth visual movement counts toward CLS. Only layout geometry displacement on the main thread generates shift scores.