Next.js Tutorial
- Next.js Introduction
- Next.js Installation
- Project Structure
- Pages & Routing
- Dynamic Routing
- Linking & Navigating
- Data Fetching (SSR)
- Data Fetching (SSG)
- Client-Side Rendering
- API Routes
- Layouts & Components
- Styling
- Image Optimization
- Font Optimization
- Script Optimization
- Middleware
- Environment Variables
- Error Handling
- Authentication
- React Server Components
- Server Actions
- Suspense & Streaming
- Caching & Revalidation
- TypeScript Integration
- Deployment
Image Optimization (`next/image`)
Unoptimized images are the number one cause of slow performance, poor Core Web Vitals, and horrible user experience on the web. Standard HTML <img> tags force the browser to download a potentially massive 5MB photo just to display it as a tiny 200px thumbnail.
The `next/image` Component
Next.js solves this completely via the Image component. It automatically optimizes images on-demand.
import Image from 'next/image';
export default function Profile() {
return (
<Image
src="/images/profile-photo.jpg" // Path from public/ dir
alt="User Profile"
width={400} // The width requested
height={400} // The height requested
/>
);
}
What does `next/image` do automatically?
- Format Conversion: It converts old formats like JPEG or PNG into next-gen formats like WebP and AVIF automatically.
- Resizing: It resizes the image down to the dimensions actually required by the user's screen (mobile vs desktop), saving megabytes of bandwidth.
- Lazy Loading: Images are only loaded when they enter the user's viewport. An image halfway down the page won't be fetched until the user scrolls there.
- Layout Shift Prevention: The component forces you to specify width/height (or a filling layout), preventing Cumulative Layout Shift (CLS) when images finally load.
Remote Images
If you want to optimize images hosted elsewhere (e.g. AWS S3, Cloudinary), you must explicitly allow those domains in your next.config.js file to protect your server from malicious actors exploiting your image processor.
// next.config.js
module.exports = {
images: {
remotePatterns: [
{
protocol: 'https',
hostname: 's3.amazonaws.com',
},
{
protocol: 'https',
hostname: 'images.unsplash.com',
},
],
},
};
Fill Layout (Responsive Images)
If you don't know the exact width/height of an image (e.g., a fluid background banner), you can use the fill prop. The image will automatically expand to fill its parent container. The parent container MUST have position: relative applied to it!
<div style={{ position: 'relative', width: '100%', height: '300px' }}>
<Image
src="/hero-bg.jpg"
alt="Hero Background"
fill
style={{ objectFit: 'cover' }}
/>
</div>
Conclusion
Using `next/image` is almost mandatory for modern Next.js development and is essential for achieving a 100/100 Google Lighthouse score. Next, we will look at how Next.js optimizes Fonts.