Next.js Image Optimization: Getting next/image Right
Swapping <img> for next/image is one of the highest-leverage performance changes in a Next.js app, but only if it's configured correctly. Here's what it does and where people get it wrong.
What It Actually Does
- Serves modern formats (WebP/AVIF) automatically, falling back for unsupported browsers
- Generates and serves correctly sized images per device via a
srcset, instead of shipping one large file to every screen - Lazy-loads offscreen images by default
- Prevents layout shift by reserving space based on the image's dimensions
Basic Usage
import Image from 'next/image';
<Image
src="/hero.jpg"
alt="Product hero shot"
width={1200}
height={630}
priority
/>
priority matters more than people realize — it preloads the image and skips lazy-loading, which is exactly what you want for anything above the fold (like a hero image), but actively hurts performance if applied to everything.
The Mistake That Kills the Benefit
Using fill without a properly sized parent container, or setting arbitrary width/height that don't match the source aspect ratio, causes either layout shift or stretched images — the exact problems this component exists to prevent.
Remote Images Need Explicit Config
// next.config.js
module.exports = {
images: {
remotePatterns: [{ protocol: 'https', hostname: 'cdn.example.com' }],
},
};
Without this, optimizing images from an external domain will fail outright — a common source of confusion the first time you point next/image at a CMS or CDN URL.