All Posts
Next.js

Next.js Image Optimization: Getting next/image Right

July 10, 2025

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.