Skip to content

Image Optimization

Images are often the largest assets on a page, making them a high-impact target for optimization. This lesson covers next/image, the built-in component that automatically resizes, compresses, and lazily loads images.

What next/image Does Automatically

The <Image> component from next/image automatically serves appropriately-sized images for the visitor's device and viewport, converts them to modern formats like WebP when supported, lazily loads images that are off-screen by default, and reserves the correct layout space upfront — directly addressing LCP and CLS, two of the three Core Web Vitals.

For local images imported directly into a component, Next.js can even determine width and height automatically from the image file itself, removing a common source of layout shift caused by images loading without reserved space.

import Image from "next/image";
import heroPhoto from "./hero.jpg"; // local import — width/height auto-detected

export default function Hero() {
  return (
    <Image
      src={heroPhoto}
      alt="Team collaborating in the office"
      priority
    />
  );
}

priority tells Next.js this image is likely above the fold and should be preloaded, improving LCP for the page's main image.

Image Component Required Props

<Image
  src="/photo.jpg"   // local path, imported file, or allowed remote URL
  alt="Description"  // required for accessibility
  width={800}        // required for remote images (not local imports)
  height={600}       // required for remote images (not local imports)
/>
  • alt is always required, both for accessibility and as a matter of API design.
  • width/height are required for remote images so Next.js can reserve layout space upfront.
  • Local, imported images (import photo from "./photo.jpg") don't need explicit width/height.
  • Remote image domains must be allow-listed in next.config.js's images.remotePatterns.

next/image Cheat Sheet

Common props and what they control.

Prop Purpose
src Image source (local import, path, or remote URL)
alt Accessible description (required)
width / height Layout dimensions (required for remote images)
priority Preloads the image; use for above-the-fold, LCP-critical images
fill Fills the parent container instead of using fixed dimensions
sizes Hints the browser which image size to fetch, for responsive layouts
quality Adjusts compression level (1–100, default 75)

Configuring Remote Images

External image URLs must be explicitly allow-listed for security, using remotePatterns in next.config.js (covered earlier in the course), before next/image will optimize them.

// next.config.js
module.exports = {
  images: {
    remotePatterns: [{ protocol: "https", hostname: "cdn.example.com" }],
  },
};

// usage
<Image src="https://cdn.example.com/photo.jpg" alt="Product" width={600} height={400} />

Responsive Images with fill

When an image should fill a container of unknown or dynamic dimensions (a card in a responsive grid, for example), fill lets the image size itself relative to its positioned parent, instead of requiring fixed pixel dimensions.

<div style={{ position: "relative", width: "100%", height: "300px" }}>
  <Image src="/photo.jpg" alt="Product" fill style={{ objectFit: "cover" }} />
</div>

The parent element needs position: relative (or similar) for fill to size correctly.

Common Mistakes

  • Using a plain <img> tag instead of next/image for content images, losing all automatic optimization.
  • Forgetting to allow-list a remote domain, causing a runtime error for external images.
  • Marking too many images priority, which defeats its purpose of highlighting the single most critical image.
  • Omitting width/height (or fill) for remote images, and being surprised by the resulting error.

Key Takeaways

  • next/image automatically resizes, compresses, and lazily loads images.
  • Local imported images auto-detect their dimensions; remote images require explicit width/height.
  • priority should be reserved for the single most important, above-the-fold image on a page.
  • Remote image domains must be allow-listed via images.remotePatterns in next.config.js.
  • fill handles responsive images inside containers with dynamic dimensions.

Pro Tip

Reserve priority for exactly the image most likely to be your page's Largest Contentful Paint element — typically a hero image or main product photo — marking multiple images priority competes for the same preloading bandwidth and can actually slow down the metric you're trying to improve.