Skip to main content

Next.js Image Optimization

Answer

Next.js provides an Image component that automatically optimizes images for better performance, including lazy loading, resizing, and modern formats.

Basic Usage

import Image from "next/image";

function Hero() {
return <Image src="/hero.jpg" alt="Hero image" width={1200} height={600} />;
}

Key Features

Image vs img Tag

// ❌ Regular img - no optimization
<img src="/large-image.jpg" alt="..." />
// - Full size downloaded
// - No lazy loading
// - No format conversion

// ✅ Next.js Image - optimized
<Image
src="/large-image.jpg"
alt="..."
width={800}
height={400}
/>
// - Resized on demand
// - Lazy loaded
// - Modern formats (WebP)
// - Prevents layout shift

Fill Mode

// For responsive images that fill container
function Card() {
return (
<div className="relative h-64 w-full">
<Image src="/product.jpg" alt="Product" fill className="object-cover" />
</div>
);
}

Sizes Prop (Responsive)

// Tell browser what size to expect at breakpoints
<Image
src="/hero.jpg"
alt="Hero"
fill
sizes="(max-width: 768px) 100vw,
(max-width: 1200px) 50vw,
33vw"
/>

// Without sizes, browser assumes 100vw
// This helps download appropriately sized images

Priority Loading

// For above-the-fold images (LCP optimization)
<Image
src="/hero.jpg"
alt="Hero"
width={1200}
height={600}
priority // Preload, no lazy loading
/>

// Use for:
// - Hero images
// - Above-fold content
// - LCP (Largest Contentful Paint) images

External Images

// next.config.js - Configure allowed domains
module.exports = {
images: {
remotePatterns: [
{
protocol: "https",
hostname: "cdn.example.com",
port: "",
pathname: "/images/**",
},
],
},
};

// Usage
<Image
src="https://cdn.example.com/images/photo.jpg"
alt="External"
width={400}
height={300}
/>;

Placeholder (Blur)

// Static import for blur placeholder
import heroImage from '../public/hero.jpg';

<Image
src={heroImage}
alt="Hero"
placeholder="blur" // Automatic blur from import
/>

// Remote images need blurDataURL
<Image
src="https://example.com/photo.jpg"
alt="Photo"
width={400}
height={300}
placeholder="blur"
blurDataURL="data:image/jpeg;base64,/9j/4AAQ..."
/>

Quality and Format

// Control output quality (1-100, default 75)
<Image
src="/photo.jpg"
alt="High quality"
width={800}
height={600}
quality={90}
/>;

// next.config.js - Default formats
module.exports = {
images: {
formats: ["image/avif", "image/webp"],
},
};

Common Patterns

// Avatar
<Image
src={user.avatar}
alt={user.name}
width={40}
height={40}
className="rounded-full"
/>

// Product gallery
<div className="grid grid-cols-2 gap-4">
{products.map(product => (
<div key={product.id} className="relative aspect-square">
<Image
src={product.image}
alt={product.name}
fill
className="object-cover"
sizes="(max-width: 768px) 50vw, 25vw"
/>
</div>
))}
</div>

// Background image
<div className="relative h-screen">
<Image
src="/background.jpg"
alt=""
fill
className="object-cover"
priority
/>
<div className="relative z-10">
{/* Content over image */}
</div>
</div>

Optimization Benefits

MetricWithout OptimizationWith Next.js Image
File sizeOriginal (1MB)50-80KB (WebP)
FormatJPEG/PNGWebP/AVIF
LoadingImmediateLazy
Layout shiftCommonPrevented

Key Points

  • Always use Image over <img> for optimization
  • width/height required (or fill)
  • Use priority for above-fold images
  • Configure remotePatterns for external images
  • Use sizes prop for responsive images
  • placeholder="blur" improves perceived performance