Lighthouse gives you a number. Field data tells you whether real users agree. Optimize for the second one.
LCP — how fast the main thing appears
The Largest Contentful Paint element is usually a hero image or a heading. Find it in DevTools before guessing at fixes.
The wins, in the order they usually pay off:
- Size the image. Always give
widthandheight, or usefillwith a sized parent. - Do not lazy-load it.
priorityon the hero, lazy on everything below the fold. - Serve modern formats. AVIF or WebP, at the size actually rendered.
- Preconnect to the image host if it is not your own origin.
<Image
src={post.coverImage}
alt={post.coverImageAlt}
width={1200}
height={630}
priority
sizes="(max-width: 768px) 100vw, 768px"
/>CLS — how much the page jumps
Layout shift is almost always something arriving late without a reserved space: an image without dimensions, a font swap, an injected banner.
/* Reserve the space before the aspect ratio is known */
.cover { aspect-ratio: 16 / 9; }For fonts, next/font handles the hard part — it self-hosts, preloads and computes a size-adjusted fallback so the swap does not reflow the page.
INP — how fast the page answers
Interaction to Next Paint replaced FID, and it is stricter: it measures the whole interaction, not just the delay before handling starts.
The usual culprits:
- A long synchronous handler blocking the main thread.
- Rendering an entire list on every keystroke.
- Too much JavaScript hydrating at once.
// Keep the input responsive, let the expensive render lag behind
const deferredQuery = useDeferredValue(query);
const results = useMemo(() => search(deferredQuery), [deferredQuery]);The structural fix is smaller client bundles. Every component that does not need to be interactive and stays on the server is JavaScript that never competes for the main thread.
Measure in the field
export function reportWebVitals(metric: NextWebVitalsMetric) {
navigator.sendBeacon("/api/vitals", JSON.stringify(metric));
}A lab score on your laptop over fibre is not the experience you are shipping. Real devices on real networks are the only data that settles an argument.