Performance · Loading performance
Image optimization (formats, responsive)
⚡ TL;DR — Images are usually the heaviest bytes on the page and the most common LCP element, so this is the highest-leverage loading work. Win on four axes: right format (AVIF/WebP over JPEG/PNG), right dimensions (
srcset/sizesso phones don't download desktop images), explicit size (kill CLS), and priority (preload/fetchprioritythe LCP image, lazy-load the rest).
🧠 Mental model
Never ship a bigger image than the device will display. That one rule generates most of the technique:
Wrong: one 2400px, 800KB JPEG served to every device
→ phone downloads 800KB to paint it at 375px (≈ 6× waste)
Right: AVIF, multiple widths, browser picks the smallest that fits
srcset 480w/960w/1440w + sizes → phone grabs the 480w at ~30KB
Two independent questions the browser must answer before layout: which file (format + resolution — solved by srcset/sizes and `
```html
<!-- ✅ Preload the LCP hero so it isn't discovered late & loaded at low priority. -->
<link rel="preload" as="image" href="hero-960.avif" type="image/avif"
imagesrcset="hero-480.avif 480w, hero-960.avif 960w" imagesizes="50vw" />
<!-- ✅ Below-the-fold images: lazy, and STILL sized to avoid CLS. -->
⚖️ Trade-offs
- AVIF is smallest but not free. It encodes much slower than JPEG/WebP (a build-time cost) and can be slower to decode on low-end devices — occasionally hurting the paint it was meant to speed up. Measure on real hardware; WebP is often the pragmatic default with AVIF as the top
<source>. <picture>art direction vssrcsetresolution switching solve different problems. Don't reach for<picture>when all you need is different sizes of the same image — plainsrcset/sizeson `` is simpler and sufficient.- Quality vs bytes is perceptual, not linear. Dropping JPEG quality 90 → 75 often halves the file with no visible difference; below ~60 artefacts show. Tune per-image, and prefer an automated image CDN over hand-exported assets.
- Don't over-engineer tiny images. A 3 KB icon doesn't need three formats and five widths. Spend the effort on the hero and the gallery.
💣 Gotchas interviewers probe
- The image is usually the LCP element — so image optimisation is LCP optimisation. Candidates who treat images as a side concern miss where the metric actually lives.
- Never lazy-load the LCP image.
loading="lazy"on the hero delays your largest paint. It's the most common regression in this whole area. - Missing
width/height→ CLS. Even with lazy loading, always reserve space. Aspect-ratio boxes are non-negotiable. sizesis what makessrcsetwork. Without it the browser assumes100vwand downloads the largest candidate — people addsrcsetand wonder why mobile still over-fetches.- Images are discovered late and loaded at low priority by default.
fetchpriority="high"+ preload for the LCP; the browser won't prioritise it for you. decoding="async"keeps image decode off the main thread so it doesn't block other rendering — cheap win on image-dense pages.- CDN/
Acceptnegotiation — a good image CDN serves AVIF/WebP based on theAcceptheader automatically, so you don't hand-maintain<picture>fallbacks. Know that this exists.
🎯 Say this in the interview
"Images are usually the heaviest bytes and the most common LCP element, so this is the highest-leverage loading work. I optimise on four axes. Format: AVIF or WebP over JPEG/PNG via
<picture>with fallbacks — AVIF is roughly half the size of JPEG. Dimensions:srcsetwithsizesso a phone downloads a 480-wide image, not the desktop 1440 — andsizesis the part people forget, without it the browser assumes 100vw and over-fetches. Stability: always setwidthandheightor an aspect-ratio so the box is reserved before load, which kills CLS. And priority: the LCP hero gets preloaded withfetchpriority=\"high\"because images are discovered late and loaded at low priority by default, while everything below the fold getsloading=\"lazy\"— but never the LCP image itself, that's the classic own-goal. In production I'd lean on an image CDN doingAccept-based format negotiation rather than hand-maintaining all of this."
🔗 Go deeper
- web.dev — Learn Images — the full course: formats, responsive images, performance.
- MDN — Responsive images —
srcset,sizes, and<picture>explained precisely. - web.dev — Optimize LCP — preloading and prioritising the LCP image.
- MDN — fetchpriority — steering the browser's resource priority.