Image Optimization
Next.js Development
Image Optimization with next/image
Images typically account for the largest share of page weight on the web, directly impacting load times, bandwidth usage, and Core Web Vitals scores. Next.js provides the next/image component that automatically optimizes images on demand: resizing, converting to modern formats like WebP and AVIF, lazy loading below the fold, and preventing Cumulative Layout Shift with automatic dimension calculation. Using next/image instead of plain <img> tags can dramatically improve your site's performance without manual image processing pipelines.
Basic Usage
The Image component requires width and height props (or the fill prop) to prevent layout shift. Next.js uses these dimensions to calculate the correct aspect ratio and reserve space before the image loads.
import Image from "next/image";
// Local image (imported — dimensions are known at build time)
import heroImage from "@/public/hero.jpg";
export default function Hero() {
return (
<section>
{/* Local image with automatic optimization */}
<Image
src={heroImage}
alt="Hero banner showing our product"
priority // Load immediately (above the fold)
placeholder="blur" // Show blur while loading
/>
{/* Remote image with explicit dimensions */}
<Image
src="https://images.unsplash.com/photo-example"
alt="Nature landscape"
width={800}
height={600}
quality={85}
/>
{/* Sized image */}
<Image
src="/logo.png"
alt="Company logo"
width={200}
height={50}
/>
</section>
);
}
Fill Mode for Responsive Images
The fill prop makes the image fill its parent container, useful for hero images, backgrounds, and flexible layouts. The parent must have position: relative.
import Image from "next/image";
function ProductCard({ product }: { product: { name: string; image: string } }) {
return (
<div className="product-card">
{/* Parent must be position: relative with defined dimensions */}
<div style={{ position: "relative", width: "100%", height: "300px" }}>
<Image
src={product.image}
alt={product.name}
fill
sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
style={{ objectFit: "cover" }}
/>
</div>
<h3>{product.name}</h3>
</div>
);
}
// With Tailwind CSS
function GalleryImage({ src, alt }: { src: string; alt: string }) {
return (
<div className="relative aspect-square">
<Image
src={src}
alt={alt}
fill
className="object-cover rounded-lg"
sizes="(max-width: 768px) 50vw, 25vw"
/>
</div>
);
}
Configuring Remote Images
To use images from external domains, configure allowed domains in next.config.js.
// next.config.js
const nextConfig = {
images: {
remotePatterns: [
{
protocol: "https",
hostname: "images.unsplash.com",
},
{
protocol: "https",
hostname: "cdn.example.com",
pathname: "/images/**",
},
{
protocol: "https",
hostname: "*.amazonaws.com",
},
],
// Image formats to serve (WebP is default, AVIF for better compression)
formats: ["image/avif", "image/webp"],
// Device sizes for responsive images
deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048],
},
};
module.exports = nextConfig;
Performance Best Practices
import Image from "next/image";
function OptimizedPage() {
return (
<div>
{/* 1. Use priority for above-the-fold images (LCP) */}
<Image src="/hero.jpg" alt="Hero" width={1200} height={600} priority />
{/* 2. Always provide sizes for responsive images */}
<Image
src="/product.jpg"
alt="Product"
width={400}
height={300}
sizes="(max-width: 768px) 100vw, 400px"
/>
{/* 3. Use placeholder="blur" for better perceived performance */}
<Image
src={localImage}
alt="Blurred placeholder"
placeholder="blur"
/>
{/* 4. Adjust quality for file size vs visual quality trade-off */}
<Image
src="/photo.jpg"
alt="Photo"
width={800}
height={600}
quality={75} // Default is 75. Lower = smaller files
/>
</div>
);
}
Tip: Always set thesizesprop on responsive images. Without it, Next.js defaults to generating images for all device sizes, which wastes bandwidth. Thesizesprop tells the browser how wide the image will be at different viewport widths, allowing it to download the smallest appropriate image.
Key Takeaways
next/imageautomatically optimizes images with resizing, format conversion, and lazy loading.- Use
priorityfor above-the-fold images to improve Largest Contentful Paint (LCP). - The
fillprop makes images fill their parent container for responsive layouts. - Configure
remotePatternsinnext.config.jsto allow external image domains. - Always provide the
sizesprop for responsive images to optimize download sizes.