What does the Next.js <Image> component do that a plain <img> doesn't?
Next/Image gives you on-the-fly resizing, modern formats (AVIF/WebP), responsive srcset, lazy loading, and reserved layout space (no CLS). Plain <img> needs you to wire all of that yourself.
Plain <img src="hero.jpg"> ships the source byte-for-byte to every device, blocks LCP if it's above-the-fold, and reflows the page when it loads (CLS). The Next.js <Image> component is a thin wrapper around <img> that adds the optimizations a production app would otherwise build by hand.
What <Image> does for you.
- On-the-fly resizing. Source is one large file; the runtime serves a per-device-width variant from
/_next/image?url=...&w=...&q=.... Smaller bytes on mobile. - Modern format negotiation. Returns AVIF or WebP when the browser sends
Accept: image/avif,image/webp, falls back to the original format otherwise. Often 30–50% smaller than JPEG/PNG. - Responsive
srcsetandsizes. Auto-generates multiple widths, lets the browser pick. You providesizesdescribing the rendered width across breakpoints. - Lazy loading by default. Off-screen images use
loading="lazy"+ IntersectionObserver. Above-the-fold images opt in withpriority(which also adds<link rel="preload">and disables lazy loading) — important for LCP. - No layout shift. Requires either explicit
width/heightorfill+ a sized parent. The component renders a placeholder of the correct aspect ratio so the page doesn't jump when the image arrives. - Optional blur placeholder.
placeholder="blur"shows a low-res preview while the full image loads — for static imports the blur data is generated at build time. - Caching. Optimized images are cached on the edge (Vercel) or filesystem (self-hosted) with long-lived
Cache-Control.
When plain <img> is fine. SVGs (already vector), tiny icons, images you've pre-optimized at build, third-party domains where you don't control caching, or when you genuinely want the simplest tag (e.g., user-uploaded avatars rendered through a CDN that already does the work).
Gotchas.
- Remote images need a config allow-list.
next.config.js→images.remotePatterns(ordomainslegacy). Otherwise the runtime refuses to optimize. fillrequires a positioned parent.<div style="position: relative; aspect-ratio: 16/9"><Image src=… fill /></div>.priorityis for the LCP image only. Marking too many as priority defeats lazy loading.- Don't pair with
unoptimizedunless you really mean it (e.g., static export with no image server). - Cost. Self-hosted optimization runs on the Node server; high traffic can spike CPU. Vercel charges per optimized image. Pre-optimization at build time (with
sharp) avoids this.
Core Web Vitals impact. Real-world wins: LCP drops by hundreds of ms because the image is smaller and preloaded; CLS drops to 0 because the slot is reserved; INP improves because lazy loading frees the main thread for interaction.
Code
Follow-up questions
- •Why does priority improve LCP and when should you NOT use it?
- •How does the optimizer pick between AVIF and WebP?
- •How would you self-host the image optimizer at scale?
- •When would you skip <Image> entirely?
Common mistakes
- •Using <img> for the LCP hero — ships full bytes, no preload, no srcset.
- •Forgetting width/height (or fill + sized parent) → CLS regression.
- •Adding priority to every image — defeats lazy loading and bloats the preload list.
- •Loading a remote CDN image without configuring remotePatterns — runtime refuses.
Performance considerations
- •Set realistic `sizes` — wrong values cause the browser to download a too-large variant.
- •Use static imports when possible: dimensions known at build, blur generated for free.
- •Cache headers on /_next/image are long-lived; bust by changing the source URL.
Edge cases
- •SVGs are not optimized — pass through as-is or use plain <img>.
- •Animated GIFs become static frames after optimization unless you set unoptimized.
- •Cross-origin srcset requires CORS headers if you also use crossOrigin.
Real-world examples
- •Vercel marketing pages, Linear's docs, Notion's blog — all rely on next/image for LCP.