Image sizes and priority
Match sizes to the rendered width; mark only the hero priority.
From next-best-practices, image.md and self-hosting.md.
Which file does each card get?
Drag the viewport and switch DPR.
fill, no sizesBadslot3 cards
Good
slot3 cards// 3 columns on desktop, 1 below 768px
<div className="relative aspect-[3/2]">
<Image src="/card.png" alt="Card" fill sizes="(max-width: 768px) 100vw, 33vw" />
</div>
// Full-width hero
<Image src="/hero.png" alt="Hero" fill sizes="100vw" />
// Fixed avatar
<Image src="/avatar.png" alt="Avatar" width={200} height={200} sizes="200px" />
// next.config.js: fewer variants
module.exports = {
images: { deviceSizes: [640, 750, 1080, 1920] },
}
When does the hero start?
Press Load page or drag the time.
<Image fill>BadLCP<Image fill priority>GoodLCP// Hero: preloaded
<Image src="/hero.png" alt="Hero" fill priority sizes="100vw" />
Priority on one image only
Scroll both feeds, then press Reload.
priority on allBadloadherototalpriority on the heroGoodloadherototal// Above the fold: the LCP image
<Image src="/hero.png" alt="Hero" fill priority sizes="100vw" />
// Below the fold: lazy by default
<Image src="/card.png" alt="Card" width={400} height={300} />
Why it matters, pros and cons
Why it matters
Without sizes the browser assumes 100vw. priority starts the hero at parse.
Pros
- Grid cards download a fraction of the bytes.
- LCP starts at HTML parse, not layout.
- Below-fold images cost nothing until scrolled near.
Cons
sizesis hand-maintained; a grid change makes it lie.priorityon many images delays the real LCP.- Next.js 16 renames
prioritytopreload.