Improving Largest Contentful Paint: the four phases and where time goes
LCP is not one number, it is four phases. Optimising the wrong one is why so much performance work produces no measurable change.
next/image automatically serves modern formats, generates responsive srcsets, lazy loads below-the-fold images and reserves layout space to prevent shift. Getting real benefit depends on two props: sizes, which tells the browser how wide the image will render, and priority, which should be set on the single LCP image and nothing else.
None of this requires configuration for local images imported from your project — Next.js reads their intrinsic dimensions at build time. Remote images need explicit dimensions and an allow-list entry in next.config.
sizes tells the browser how wide the image will be at each breakpoint, so it can pick the right file from the srcset before layout is known.
This is the most commonly wrong prop in Next.js codebases. Without sizes, a responsive image defaults to 100vw — the browser assumes full viewport width and downloads the largest candidate. On a 2560px desktop, a thumbnail rendered at 300px can pull down a 2560px file.
// A card image in a 3-column grid at desktop, 2 at tablet, 1 at mobile
<Image
src={cover}
alt="Dashboard redesign case study cover"
width={800}
height={450}
sizes="(max-width: 640px) 100vw, (max-width: 1024px) 50vw, 33vw"
/>On the LCP element only — usually the hero image or the featured image of an article. priority disables lazy loading and adds a preload hint so the request starts during HTML parsing rather than after layout.
Setting priority on many images is actively harmful: preload hints compete for bandwidth and connections, delaying the one image that determines your LCP score. If a page has six priority images, none of them is prioritised.
| Image position | Recommended props |
|---|---|
| Hero / above the fold, largest | priority, explicit sizes |
| Above the fold, secondary | loading="eager", no priority |
| Below the fold | Default (lazy) |
| Decorative background | CSS background or alt="" with lazy loading |
Alt text has two jobs: describing the image to screen reader users, and giving search engines context. Both are served by a plain description of what the image shows and why it is there — not a keyword list.
Yes. Even on a five-page site, format conversion and correct dimensions typically cut image payload by 40–70%, and the automatic dimension reservation removes a whole class of layout-shift bugs.
Enable both. AVIF is typically 20–30% smaller than WebP at similar quality but encodes slower; browsers that support it will request it, and others fall back to WebP.
Either width and height are missing, or CSS is overriding the aspect ratio. Give the component real intrinsic dimensions and let CSS scale it with width: 100%; height: auto.
Yes — configure a custom loader so the component builds URLs for your CDN's transformation API instead of using the built-in optimiser. You keep the responsive srcset behaviour and offload the processing.
ROVQIX Engineering
Engineering team, ROVQIX
The ROVQIX engineering team builds and maintains web platforms, APIs and infrastructure for clients across SaaS, ecommerce and enterprise. These notes come out of real production work — deploys, incidents, migrations and audits.
ROVQIXdesigns and builds production web platforms — Next.js front ends, Node.js APIs and the infrastructure behind them. Tell us what you're building and we'll scope it with you.
LCP is not one number, it is four phases. Optimising the wrong one is why so much performance work produces no measurable change.
CLS is the most fixable Core Web Vital. Almost every point of it comes from an element that did not tell the browser how big it would be.
Search engines still cannot see your images. Everything they know comes from the filename, the alt text and the words around it.
No spam. Just the occasional case study and craft breakdown.