Next.jsPerformanceImagesOptimization

Next.js Image Optimization: Using the Image Component

Learn how to optimize images in Next.js using the built-in Image component. Improve performance, reduce bandwidth, and enhance user experience.

By Vibe Code Basics9 min read
Next.js Image Optimization: Using the Image Component

Next.js Image Optimization: Using the Image Component

Images are often the largest assets on a webpage, significantly impacting performance. Next.js provides a powerful Image component that automatically optimizes images for you. Let's explore how to use it effectively.

If you're just getting started, check out our Getting Started with Next.js guide.

Why Use the Next.js Image Component?

The Next.js Image component provides:

  • Automatic optimization: Images are automatically optimized on-demand
  • Lazy loading: Images load only when they enter the viewport
  • Responsive images: Automatically serves the right size for each device
  • Modern formats: Automatically serves WebP or AVIF when supported
  • Prevent layout shift: Prevents Cumulative Layout Shift (CLS)

Basic Usage

Import and use the Image component:

import Image from 'next/image';

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

Important: You must specify width and height for static images to prevent layout shift.

External Images

For images from external domains, configure them in next.config.js:

// next.config.js
const nextConfig = {
  images: {
    remotePatterns: [
      {
        protocol: 'https',
        hostname: 'example.com',
        pathname: '/images/**',
      },
    ],
  },
};

export default nextConfig;

Then use them:

<Image
  src="https://example.com/images/photo.jpg"
  alt="Photo"
  width={800}
  height={600}
/>

Responsive Images

Use the fill prop for responsive images that fill their container:

<div style={{ position: 'relative', width: '100%', height: '400px' }}>
  <Image
    src="/hero.jpg"
    alt="Hero"
    fill
    style={{ objectFit: 'cover' }}
  />
</div>

Or use sizes for responsive images:

<Image
  src="/hero.jpg"
  alt="Hero"
  width={1200}
  height={600}
  sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
/>

Image Priority

For above-the-fold images, use the priority prop to disable lazy loading:

<Image
  src="/hero.jpg"
  alt="Hero"
  width={1200}
  height={600}
  priority
/>

Image Placeholders

Blur Placeholder

Add a blur placeholder for better UX:

<Image
  src="/photo.jpg"
  alt="Photo"
  width={800}
  height={600}
  placeholder="blur"
  blurDataURL="data:image/jpeg;base64,..."
/>

Generate Blur Data URL

You can generate blur data URLs using tools or libraries:

import { getPlaiceholder } from 'plaiceholder';

const { base64 } = await getPlaiceholder('/photo.jpg');

<Image
  src="/photo.jpg"
  alt="Photo"
  width={800}
  height={600}
  placeholder="blur"
  blurDataURL={base64}
/>

Styling Images

You can style images using the style prop or className:

<Image
  src="/photo.jpg"
  alt="Photo"
  width={800}
  height={600}
  className="rounded-lg shadow-lg"
  style={{ borderRadius: '8px' }}
/>

Image Optimization Configuration

Configure image optimization in next.config.js:

const nextConfig = {
  images: {
    formats: ['image/avif', 'image/webp'],
    deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048, 3840],
    imageSizes: [16, 32, 48, 64, 96, 128, 256, 384],
    minimumCacheTTL: 60,
  },
};

export default nextConfig;

Common Patterns

Hero Image

<div className="relative w-full h-96">
  <Image
    src="/hero.jpg"
    alt="Hero"
    fill
    priority
    className="object-cover"
  />
  <div className="absolute inset-0 flex items-center justify-center">
    <h1 className="text-white text-4xl">Welcome</h1>
  </div>
</div>

Avatar

<Image
  src="/avatar.jpg"
  alt="Avatar"
  width={64}
  height={64}
  className="rounded-full"
/>

Gallery

<div className="grid grid-cols-3 gap-4">
  {images.map((image) => (
    <Image
      key={image.id}
      src={image.src}
      alt={image.alt}
      width={300}
      height={300}
      className="rounded-lg"
    />
  ))}
</div>

Performance Tips

  1. Use appropriate sizes: Don't serve larger images than needed
  2. Leverage lazy loading: Let images load as users scroll
  3. Use priority sparingly: Only for above-the-fold images
  4. Optimize source images: Compress images before uploading
  5. Use modern formats: Let Next.js serve WebP/AVIF automatically

Comparison: Regular img vs Next.js Image

Regular img tag:

<img src="/photo.jpg" alt="Photo" />
  • No optimization
  • No lazy loading
  • Can cause layout shift
  • Larger file sizes

Next.js Image:

<Image src="/photo.jpg" alt="Photo" width={800} height={600} />
  • Automatic optimization
  • Lazy loading by default
  • Prevents layout shift
  • Smaller file sizes
  • Modern formats

Troubleshooting

Images not loading

  • Check if external domains are configured in next.config.js
  • Verify the image path is correct
  • Check browser console for errors

Layout shift

  • Always specify width and height for static images
  • Use fill with a positioned container for responsive images

Blurry images

  • Ensure source images are high quality
  • Check if sizes prop is correctly configured

Conclusion

The Next.js Image component is essential for building performant applications. By using it, you automatically get optimizations that would take significant effort to implement manually.

Next Steps:

Happy optimizing! 🚀

Related Articles