LearnAI ToolsCareerPractice BuildsPlayContact
Lesson 3616 min read

Image Optimization

Serve perfectly sized, lazy-loaded, modern-format images automatically using the next/image component.

The Problem with <img>

A plain <img> tag sends whatever file size exists, at full resolution, to every device — a phone on a slow connection downloads the exact same multi-megabyte photo as a 4K desktop monitor. It also has no built-in lazy loading and can cause layout shift while it loads.

The Image Component

next/image automatically resizes images to fit the device, serves modern formats like WebP or AVIF where supported, lazy-loads images outside the viewport by default, and reserves the correct space to avoid layout shift.

import Image from 'next/image';
export default function Avatar() {
return (
<Image
src="/profile.png"
alt="User profile photo"
width={128}
height={128}
/>
);
}
width and height Are Required

Next.js needs the intrinsic dimensions to reserve the right amount of space before the image loads, preventing layout shift — for local images it can infer these, but for remote images you must specify them explicitly (or use the fill prop).

Local vs Remote Images

Importing a local image lets Next.js automatically determine its width and height for you.

import Image from 'next/image';
import heroImg from './hero.png'; // width/height inferred automatically
export default function Hero() {
return <Image src={heroImg} alt="Product hero shot" />;
}

Remote images require the domain to be explicitly allowed in next.config.js, as a security measure against optimizing arbitrary external URLs.

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

Priority Loading

The largest, most important image on a page — often called the Largest Contentful Paint (LCP) element — should skip lazy loading, since it needs to appear as quickly as possible.

<Image
src={heroImg}
alt="Product hero shot"
priority // loads immediately, not lazily
/>

Common Beginner Mistakes

Forgetting to add a remote domain to next.config.js

This throws a build/runtime error — every external image domain used with next/image must be explicitly allow-listed.

Adding priority to every image on the page

This defeats lazy loading entirely — reserve priority for the one or two images visible immediately on load.

FAQs

Yes, though SVGs are vector images and generally don't benefit from the same resizing optimization as raster formats like JPEG or PNG.

Yes — the optimization runs through Next.js's own image handling, but you can also configure an external loader if your host needs a different optimization service.

Summary

next/image handles resizing, format selection, and lazy loading automatically, for a meaningfully faster and more stable page. Next, you'll see the equivalent optimization Next.js applies to fonts.

Next Lesson →

Font Optimization