next/image: On-Demand Sharp Resizing & WebP/AVIF Conversion
- Last updated
- Prerequisites:
- HTML <img> and <picture> elements
- Core Web Vitals (LCP/CLS)
- nextjs
- next-image
- sharp
- webp
- avif
- lcp
- performance
Read at your depth
The practical view
`next/image` extends HTML `<img>` with automatic image optimization. It serves images in modern formats (AVIF/WebP), automatically generates responsive `srcset` attributes based on device sizes, resizes images on-demand on the server using the high-performance `sharp` library, and prevents Cumulative Layout Shift (CLS) by requiring explicit `width`/`height` or `fill`.
The same idea in other frameworks
Standard `<img>` with manual build-time responsive image generators (like Vite imagetools).`NgOptimizedImage` directive with third-party CDN image loader integration.Nuxt Image (`<NuxtImg>` / `<NuxtPicture>`) with IPX on-demand transformation.SvelteKit `@sveltejs/enhanced-img` build-time image pipeline.Legacy vs modern
Unoptimized standard <img> vs next/image pipeline
Standard `<img>` sends heavy uncompressed images and causes layout shifts; `next/image` generates responsive formats and enforces aspect ratios.
<img src="/large-hero.jpg" alt="Hero" /> <!-- ❌ OLD: Huge payload, no AVIF/WebP, layout shift --><Image src="/large-hero.jpg" alt="Hero" width={1200} height={600} priority /> <!-- ✅ NEW -->Interview gotchas
Context
Interviewers test your awareness of server-side security and Denial of Service (DoS) protection.
The mechanical answer
Because `next/image` proxies and transforms images on the server on demand, an open optimizer without domain whitelisting would act as an open proxy. Attackers could flood `/_next/image?url=https://attacker.com/huge.png` to consume CPU, memory, and bandwidth. Next.js enforces `images.remotePatterns` to strictly whitelist authorized upstream asset origins.
Trap
Never use wide-open wildcard patterns (`hostname: '**'`) in production configs as it exposes the optimization server to SSRF and DoS vectors.
Context
This checks practical responsive CSS layout integration.
The mechanical answer
Use `fill` when the exact pixel dimensions are unknown in advance (e.g. dynamic responsive cards or background hero sections). With `fill`, the image styles automatically set `position: absolute; inset: 0; width: 100%; height: 100%;`. The parent element must explicitly specify `position: relative`, `position: fixed`, or `position: absolute` with a designated aspect ratio or height.
Trap
Using `fill` on an element whose parent is statically positioned will cause the image to expand across the nearest positioned ancestor or the entire viewport.