Performance details

Did the paragraph jump when the hero loaded? That's CLS. It's preventable.

Image dimensions for CLS

Every <img> and <video> needs explicit width and height. Without them, the browser reserves zero space until the image loads, then content jumps.

Set intrinsic dimensions as HTML attributes:

Or use aspect-ratio in CSS:

Next.js <Image> requires width and height (or fill) and handles this automatically.

fetchpriority and loading

fetchpriority="high": use for the LCP element only. In Next.js: <Image priority />.

loading="lazy": defers until near viewport. Never on the LCP image.

Font loading: preload, preconnect, font-display

1. Preconnect to the font CDN

2. Preload critical fonts

crossorigin is required or the browser double-fetches. Preload only fonts used above the fold.

3. font-display: swap

Tune fallback metrics to reduce the visible shift:

Virtualization for large lists

Past ~50 items, render only rows in or near the viewport. 10,000 items, ~30 DOM nodes.

For lists that don't justify full virtualization, content-visibility: auto skips layout and paint for off-screen blocks:

Virtualization breaks Cmd/Ctrl+F, anchor links, and print views. Plan for these if they matter.

Common mistakes