Next.js Image Optimization — next/image Guide
Advertisement
Next.js Image Optimization — next/image Guide
The next/image component automatically optimizes images for performance, handling responsive sizing, format conversion, and lazy loading.
- Next.js Image Optimization — next/image Guide
- Why next/image?
- Basic Usage
- Remote Images
- Responsive Images
- Lazy Loading
- Styling Images
- Fill Container Pattern
- OnLoad and Error Handling
- External Images Configuration
- Image Placeholder
- Optimized Formats
- Performance Tips
- Common Issues
- FAQ
Why next/image?
Standard HTML images have performance issues:
- No automatic optimization for different screen sizes
- No format conversion (WEBP, AVIF)
- Layout shift while loading
- Unnecessary data transfer to mobile devices
next/image solves all these problems.
Basic Usage
// app/page.tsx
import Image from 'next/image'
import heroImage from '@/public/hero.jpg'
export default function HomePage() {
return (
<Image
src={heroImage}
alt="Hero image"
width={1200}
height={600}
/>
)
}
When using imported images, dimensions are automatic.
Remote Images
For remote URLs, specify dimensions:
import Image from 'next/image'
export default function BlogPost() {
return (
<Image
src="https://cdn.example.com/posts/featured.jpg"
alt="Featured image"
width={800}
height={400}
/>
)
}
Responsive Images
Use sizes for responsive optimization:
import Image from 'next/image'
export default function ResponsiveImage() {
return (
<Image
src="/hero.jpg"
alt="Hero"
width={1200}
height={600}
sizes="(max-width: 640px) 100vw,
(max-width: 1024px) 75vw,
50vw"
priority
/>
)
}
The sizes prop tells Next.js which image sizes to generate.
Lazy Loading
Images load lazily by default:
import Image from 'next/image'
export default function PostList() {
return (
<div>
{posts.map(post => (
<Image
key={post.id}
src={post.image}
alt={post.title}
width={300}
height={200}
loading="lazy" // Default
/>
))}
</div>
)
}
Use loading="eager" for above-the-fold images:
<Image
src="/hero.jpg"
alt="Hero"
width={1200}
height={600}
priority // Same as loading="eager"
/>
Styling Images
Apply CSS to next/image:
import Image from 'next/image'
export default function StyledImage() {
return (
<Image
src="/photo.jpg"
alt="Photo"
width={400}
height={300}
className="rounded-lg shadow-lg"
/>
)
}
Or use a wrapper div:
import Image from 'next/image'
export default function WrappedImage() {
return (
<div className="relative w-full h-80">
<Image
src="/photo.jpg"
alt="Photo"
fill
className="object-cover"
/>
</div>
)
}
The fill prop makes the image fill its container.
Fill Container Pattern
Use fill for unknown dimensions:
import Image from 'next/image'
export default function ResponsiveCard() {
return (
<div className="relative w-full aspect-video">
<Image
src="/card-image.jpg"
alt="Card"
fill
className="object-cover rounded-lg"
/>
</div>
)
}
OnLoad and Error Handling
Handle image events:
'use client'
import { useState } from 'react'
import Image from 'next/image'
export default function ImageWithFallback() {
const [hasError, setHasError] = useState(false)
if (hasError) {
return <div className="bg-gray-200 w-full h-64" />
}
return (
<Image
src="/image.jpg"
alt="Image"
width={600}
height={400}
onError={() => setHasError(true)}
onLoadingComplete={(result) => {
console.log('Image loaded:', result)
}}
/>
)
}
External Images Configuration
Allow external image domains:
// next.config.js
export default {
images: {
remotePatterns: [
{
protocol: 'https',
hostname: 'cdn.example.com',
port: '',
pathname: '/assets/**'
},
{
protocol: 'https',
hostname: 'images.unsplash.com'
}
]
}
}
Image Placeholder
Show placeholder while loading:
import Image from 'next/image'
export default function ImageWithPlaceholder() {
return (
<Image
src="/large-image.jpg"
alt="Image"
width={800}
height={600}
placeholder="blur"
blurDataURL="data:image/svg+xml,%3Csvg..."
/>
)
}
Optimized Formats
Next.js automatically serves optimal formats:
// Serves WebP on Chrome, AVIF on modern browsers, JPG fallback
<Image
src="/image.jpg"
alt="Optimized"
width={800}
height={600}
/>
Performance Tips
Preload Critical Images:
import { preloadImage } from 'next/image'
export default function Page() {
preloadImage('/hero.jpg', 'image')
return <Image src="/hero.jpg" alt="Hero" width={1200} height={600} />
}
Quality Control:
<Image
src="/image.jpg"
alt="Image"
width={800}
height={600}
quality={85} // Default is 75
/>
Device Pixel Ratio:
<Image
src="/image.jpg"
alt="Image"
width={800}
height={600}
priority
/>
Common Issues
Issue: Layout shift Solution: Always provide width/height or use fill with aspect ratio.
Issue: Blurry images on high-DPI screens Solution: Increase width/height or use quality prop.
FAQ
Q: Do I have to use next/image? A: No, but it's highly recommended for performance. Standard img tags work but miss optimization benefits.
Q: Can I use SVGs with next/image? A: SVGs work but don't get optimized. Use standard img tags for SVGs.
Q: How do I implement an image gallery? A: Map over images and render multiple next/image components with appropriate styling.
Master image optimization to significantly improve Core Web Vitals.
Advertisement