乐闻世界logo
搜索文章和话题

How does Next.js image optimization work?

2月17日 23:30

Next.js image optimization feature is provided through the next/image component, which is a powerful tool that automatically optimizes images to improve performance and user experience.

next/image Component Basics

Basic Usage

javascript
import Image from 'next/image'; export default function Page() { return ( <Image src="/hero.jpg" alt="Hero image" width={800} height={600} /> ); }

Required Props

  • src: Image path (local or remote)
  • width: Image width (integer)
  • height: Image height (integer)
  • alt: Alternative text (for accessibility)

Image Optimization Features

1. Automatic Format Conversion

Next.js automatically converts images to modern formats (WebP, AVIF) to reduce file size.

javascript
<Image src="/photo.jpg" alt="Photo" width={800} height={600} // Automatically converts to WebP or AVIF />

2. Responsive Images

Automatically generates different image sizes and loads appropriate size based on device.

javascript
<Image src="/responsive.jpg" alt="Responsive image" width={1200} height={800} sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw" // Generates multiple sizes: 640w, 750w, 828w, 1080w, 1200w, 1920w, 2048w, 3840w />

3. Lazy Loading

By default, images are lazy loaded and only load when they enter the viewport.

javascript
<Image src="/lazy.jpg" alt="Lazy loaded image" width={800} height={600} // Lazy loading enabled by default /> // Disable lazy loading (above-the-fold images) <Image src="/hero.jpg" alt="Hero image" width={800} height={600} priority // Disables lazy loading, loads with priority />

4. Blur Placeholder

Displays a blurred placeholder before image loads, improving user experience.

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

5. Prevent Layout Shift

By setting explicit width and height, prevents layout shift when image loads.

javascript
<Image src="/photo.jpg" alt="Photo" width={800} height={600} // Reserves space, prevents layout shift />

Advanced Usage

1. Remote Images

Configure allowed remote image domains.

javascript
// next.config.js module.exports = { images: { remotePatterns: [ { protocol: 'https', hostname: 'example.com', port: '', pathname: '/images/**', }, { protocol: 'https', hostname: 'cdn.example.com', }, ], }, };

Using remote images:

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

2. Dynamic Images

javascript
import Image from 'next/image'; export default function ProductGallery({ images }) { return ( <div> {images.map((image) => ( <Image key={image.id} src={image.url} alt={image.alt} width={image.width} height={image.height} placeholder="blur" blurDataURL={image.blurDataURL} /> ))} </div> ); }

3. Image Fill Mode

javascript
<Image src="/photo.jpg" alt="Photo" width={800} height={600} fill // Fills parent container style={{ objectFit: 'cover' }} />

4. Image Quality Control

javascript
<Image src="/photo.jpg" alt="Photo" width={800} height={600} quality={80} // Default 75, range 1-100 />

5. Custom Loader

javascript
import Image from 'next/image'; const imageLoader = ({ src, width, quality }) => { return `https://cdn.example.com/${src}?w=${width}&q=${quality || 75}`; }; export default function Page() { return ( <Image loader={imageLoader} src="photo.jpg" alt="Photo" width={800} height={600} /> ); }

Configuration Options

next.config.js Configuration

javascript
// next.config.js module.exports = { images: { // Device sizes deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048, 3840], // Image sizes imageSizes: [16, 32, 48, 64, 96, 128, 256, 384], // Image formats formats: ['image/avif', 'image/webp'], // Minimum cache TTL (seconds) minimumCacheTTL: 60, // Disable static imports disableStaticImages: false, // Disable optimization unoptimized: false, // Dangerously allow all domains (not recommended) dangerouslyAllowSVG: false, // Content security policy contentSecurityPolicy: "default-src 'self'; script-src 'none'; sandbox;", // Content disposition type contentDispositionType: 'attachment', // Remote image patterns remotePatterns: [ { protocol: 'https', hostname: 'example.com', port: '', pathname: '/images/**', }, ], // Domain list (deprecated, use remotePatterns) domains: ['example.com'], }, };

Real-world Use Cases

1. E-commerce Product Images

javascript
import Image from 'next/image'; export default function ProductCard({ product }) { return ( <div className="product-card"> <Image src={product.image} alt={product.name} width={400} height={400} priority // Above-the-fold products load with priority placeholder="blur" blurDataURL={product.blurDataURL} sizes="(max-width: 640px) 100vw, (max-width: 1024px) 50vw, 33vw" /> <h3>{product.name}</h3> <p>${product.price}</p> </div> ); }

2. Blog Post Cover Images

javascript
import Image from 'next/image'; export default function BlogPost({ post }) { return ( <article> <Image src={post.coverImage} alt={post.title} width={1200} height={630} priority // Blog post covers load with priority placeholder="blur" blurDataURL={post.blurDataURL} sizes="100vw" /> <h1>{post.title}</h1> <p>{post.excerpt}</p> </article> ); }

3. User Avatars

javascript
import Image from 'next/image'; export default function UserAvatar({ user, size = 40 }) { return ( <div className="avatar"> <Image src={user.avatar || '/default-avatar.png'} alt={user.name} width={size} height={size} className="rounded-full" placeholder="blur" blurDataURL={user.blurDataURL} /> </div> ); }
javascript
'use client'; import { useState } from 'react'; import Image from 'next/image'; export default function ImageGallery({ images }) { const [selectedIndex, setSelectedIndex] = useState(0); return ( <div className="gallery"> <div className="main-image"> <Image src={images[selectedIndex].url} alt={images[selectedIndex].alt} width={1200} height={800} priority placeholder="blur" blurDataURL={images[selectedIndex].blurDataURL} /> </div> <div className="thumbnails"> {images.map((image, index) => ( <button key={image.id} onClick={() => setSelectedIndex(index)} className={index === selectedIndex ? 'active' : ''} > <Image src={image.url} alt={image.alt} width={150} height={100} placeholder="blur" blurDataURL={image.blurDataURL} /> </button> ))} </div> </div> ); }

5. Responsive Hero Image

javascript
import Image from 'next/image'; export default function HeroSection() { return ( <section className="hero"> <Image src="/hero.jpg" alt="Hero image" width={1920} height={1080} priority placeholder="blur" blurDataURL="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBD..." sizes="100vw" style={{ width: '100%', height: 'auto', objectFit: 'cover', }} /> <div className="hero-content"> <h1>Welcome to Our Site</h1> <p>Discover amazing content</p> </div> </section> ); }

Performance Optimization Tips

1. Use blurDataURL

javascript
// Generate blur placeholder import { getPlaiceholder } from 'plaiceholder'; export async function getBlurDataURL(src) { const buffer = await fetch(src).then(res => res.arrayBuffer()); const { base64 } = await getPlaiceholder(buffer); return base64; } // Usage const blurDataURL = await getBlurDataURL('/photo.jpg'); <Image src="/photo.jpg" alt="Photo" width={800} height={600} placeholder="blur" blurDataURL={blurDataURL} />

2. Optimize Image Sizes

javascript
// Use appropriate sizes for different scenarios // Small thumbnail <Image src="/thumb.jpg" alt="Thumbnail" width={150} height={150} /> // Medium image <Image src="/medium.jpg" alt="Medium" width={400} height={300} /> // Large image <Image src="/large.jpg" alt="Large" width={1200} height={800} />

3. Use Appropriate Image Formats

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

4. Lazy Load Non-critical Images

javascript
// Above-the-fold images use priority <Image src="/hero.jpg" alt="Hero" width={800} height={600} priority /> // Below-the-fold images use default lazy loading <Image src="/below-fold.jpg" alt="Below fold" width={800} height={600} />

5. Use CDN for Acceleration

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

Best Practices

1. Always Provide Alt Text

javascript
// ✅ Good practice <Image src="/photo.jpg" alt="A beautiful sunset over the ocean" width={800} height={600} /> // ❌ Bad practice <Image src="/photo.jpg" alt="" width={800} height={600} />

2. Set Priority for Above-the-fold Images

javascript
// ✅ Good practice: Above-the-fold images load with priority <Image src="/hero.jpg" alt="Hero" width={800} height={600} priority /> // ❌ Bad practice: All images set to priority <Image src="/below-fold.jpg" alt="Below fold" width={800} height={600} priority // Unnecessary priority loading />

3. Use Appropriate sizes Attribute

javascript
// ✅ Good practice: Set sizes based on layout <Image src="/photo.jpg" alt="Photo" width={800} height={600} sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw" /> // ❌ Bad practice: Don't set sizes <Image src="/photo.jpg" alt="Photo" width={800} height={600} // Browser will assume image fills viewport />

4. Optimize Image Quality

javascript
// ✅ Good practice: Adjust quality based on image type <Image src="/photo.jpg" alt="Photo" width={800} height={600} quality={80} // Photos use higher quality /> <Image src="/icon.png" alt="Icon" width={64} height={64} quality={90} // Icons use even higher quality /> // ❌ Bad practice: All images use same quality <Image src="/photo.jpg" alt="Photo" width={800} height={600} quality={100} // Unnecessarily high quality />

5. Use Placeholders to Improve User Experience

javascript
// ✅ Good practice: Use blur placeholder <Image src="/photo.jpg" alt="Photo" width={800} height={600} placeholder="blur" blurDataURL="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBD..." /> // ❌ Bad practice: Don't use placeholder <Image src="/photo.jpg" alt="Photo" width={800} height={600} // Shows blank space before image loads />

Common Questions

Q: How to handle dynamic images?

A: Use dynamic imports or fetch image info from API.

javascript
import Image from 'next/image'; export default async function DynamicImagePage() { const images = await fetch('/api/images').then(res => res.json()); return ( <div> {images.map(image => ( <Image key={image.id} src={image.url} alt={image.alt} width={image.width} height={image.height} /> ))} </div> ); }

Q: How to disable image optimization?

A: Set unoptimized: true in next.config.js.

javascript
module.exports = { images: { unoptimized: true, }, };

Q: How to handle SVG images?

A: SVG images require special configuration.

javascript
module.exports = { images: { dangerouslyAllowSVG: true, contentSecurityPolicy: "default-src 'self'; script-src 'none'; sandbox;", }, };

Next.js image optimization feature can significantly improve application performance and user experience. By properly using the next/image component and configuration options, you can build high-performance image display solutions.

标签:Next.js