Skip to content
fearchitect
Performance Engineering

Image & Asset Strategy

Serve the smallest correct image; preload the LCP one.

By Abas TurabliReviewed

Summary

Images and fonts are the biggest drag on LCP and CLS. Modern formats (AVIF, WebP) cut payload 30–50% over JPEG. Responsive `srcset`/`sizes` delivers the right resolution per viewport. The LCP image needs `fetchPriority="high"` and a preload link; everything below the fold gets `loading="lazy"`. Width and height attributes prevent CLS.

Jump to the interview angle

What controls image performance

  • AVIF compresses 40–50% smaller than JPEG at equal quality; WebP saves ~30% and decodes faster.
  • `next/image` defaults to WebP only — opt into AVIF with `formats: ['image/avif', 'image/webp']` in `next.config`.
  • `fetchPriority="high"` raises the LCP image's fetch priority; pair with `preload` to discover it before `<body>` parses.
  • The `priority` prop is deprecated in Next.js 16 — use `preload` and `fetchPriority` as separate props.
  • Without `sizes`, the browser assumes 100vw and downloads a full-screen image on every device.
  • Explicit `width`/`height` attributes (or `aspect-ratio`) let the browser reserve space before the image loads, preventing CLS.
  • `font-display: swap` renders text in a fallback face immediately; pair with `<link rel="preconnect">` to cut DNS + TLS time.

LCP hero with preload + fetchPriority (Next.js 16)

Use preload to emit <link rel="preload"> and fetchPriority="high" to raise request priority. The deprecated priority prop did both; in Next.js 16 they are separate.

Hero image with preload + fetchPriority (next/image, Next.js 16)tsx
import Image from "next/image";

// LCP image: preload emits <link rel="preload">; fetchPriority raises fetch priority.
// priority is deprecated in Next.js 16 — use preload + fetchPriority instead.
export function Hero() {
  return (
    <Image
      src="/hero.jpg"
      alt="Product hero"
      width={1200}
      height={630}
      preload           // emits <link rel="preload"> in <head>
      fetchPriority="high"  // raises request from low to high priority
      sizes="(max-width: 768px) 100vw, 1200px"
      quality={75}     // default qualities allowlist is [75]; other values snap to nearest
      className="w-full h-auto"
    />
  );
}

preload emits <link rel="preload">; fetchPriority="high" raises priority. sizes stops a 1200 px download on a 375 px phone.

fetchPriority=high raises the LCP image from low to high priority in the preload scanner; lazy images are deferred until near-viewport.

Format and priority trade-offs

Pros

  • AVIF/WebP reduce image payload 30–50%, directly improving LCP on slow connections.
  • `fetchPriority="high"` on the LCP image can cut LCP by 200–500 ms without code changes.
  • Native lazy-loading is zero-JS: the browser handles deferral and intersection natively.
  • `next/image` automates format negotiation and srcset generation.
  • Width/height attributes eliminate image-driven CLS at the HTML level.

Cons

  • AVIF encoding is slow; build-time generation at multiple sizes raises deploy times.
  • Misconfigured `sizes` causes the browser to fetch a larger image than needed.
  • Preloading too many images wastes bandwidth and delays more important resources.
  • `font-display: swap` causes a flash of unstyled text (FOUT) until the web font loads.

Never lazy-load the LCP image

loading="lazy" defers the fetch until the image is near-viewport — the LCP image is already in the viewport, so this delays it past the measurement window. Add fetchPriority="high" instead. Also avoid adding high priority to more than one or two images; it loses meaning if overused.

Interview angle

Interviewers frame this as LCP diagnosis: walk from network request to pixel. The browser deprioritizes images by default; fetchPriority="high" raises it — pair with preload to discover the request early. CLS from images is solved at the HTML level with width/height, not JavaScript.

Soundbite: "LCP image gets preload and fetchPriority high, never lazy. Everything else gets lazy-loading and explicit dimensions. next/image defaults to WebP; opt into AVIF via next.config."

Key terms

LCP (Largest Contentful Paint)
The time until the largest above-fold image or text block renders.
fetchpriority / fetchPriority
HTML attribute (JSX prop) that raises ("high") or lowers ("low") a resource fetch priority.
srcset / sizes
HTML attributes that list candidate image URLs and layout widths so the browser picks the best fit.
CLS (Cumulative Layout Shift)
Score for unexpected layout movement; images without dimensions are a top cause.
font-display: swap
CSS descriptor that renders text in a fallback font immediately, swapping the web font when loaded.

Further reading

Search fearchitect

Jump to a topic, mode, or action.