Images can slow your website down. In modern web development, performance matters. That’s why Next.js continues to improve its image optimization features. Whether your images are stored locally or served remotely, you can now easily control and improve performance.
Why Image Optimization Matters
Fast websites keep users engaged. Unoptimized images increase load times, waste bandwidth, and harm SEO. In contrast, optimized images:
- Load faster
- Reduce bounce rates
- Improve Core Web Vitals
- Save mobile data
Next.js provides a powerful <Image /> Components to tackle these issues. It does more than just render an image. It automates compression, resizing, and lazy loading by default.
However, first, let’s examine the basic setup.
Getting Started with Next.js

Optimizing Local Images
Local images are stored inside your project folder. Usually, they live in /public or any directory you choose.
my-nextjs-app/ ├── public/ │ ├── sample.png │ └── favicon.ico ├── app/ │ ├── page.tsx │ └── layout.tsx ├── components/ │ └── HomePage.tsx ├── styles/ ├── .gitignore ├── next.config.js ├── package.json └── tsconfig.json
Here’s how you optimize a local image:
import Image from "next/image";
import myImage from "../../public/sample.png";
export default function HomePage() {
return (
<div>
<h1>Welcome to My Site</h1>
<Image
priority
alt="A beautiful scene"
height={600}
src={myImage}
width={800}
/>
</div>
);
}Let’s break this down.

What Happens Behind the Scenes?
- The image gets resized and compressed.
- Lazy loading is disabled because of
priority. - The image is served in modern formats, such as WebP, when supported.
Benefits of Local Images
- No network requests to third-party hosts.
- You control the file size and quality.
- Builds are faster since images are processed locally.
Still, you must use the correct image dimensions. If you skip width and height, layout shifts may occur.
To fix this, either:
- Use static dimensions as shown above, or
- Use
filllayout with a parent container and position styles.
import Image from "next/image";
import myImage from "../../public/sample.png";
export default function HomePage() {
return (
<div>
<h1>Welcome to My Site</h1>
<div style={{ position: "relative", width: "100%", height: "500px" }}>
<Image
fill
alt="Scenery"
src={myImage}
style={{ objectFit: "cover" }}
/>
</div>
</div>
);
}That’s it for local images. Let’s now talk about remote ones.

Optimizing Remote Images
You often fetch images from external URLs, such as CDNs, APIs, or headless CMS platforms. Optimizing these can be tricky. Thankfully, Next.js makes it easy.
Step 1: Configure next.config.js
Before using remote images, you need to declare their domains:
// next.config.js
module.exports = {
images: {
remotePatterns: [
{
protocol: 'https',
hostname: 'ucarecdn.com',
pathname: '/**',
},
],
},
};This ensures Next.js can safely optimize those images.
Step 2: Use the Image Component
import Image from 'next/image';
export default function Product() {
return (
<Image
src="https://ucarecdn.com/9f95f994-a45a-4b60-a6e3-f8f34b2262e3/image.jpg"
alt="Product Display"
width={600}
height={400}
/>
);
}Just like local images, you get:
- Automatic compression
- Format conversion
- Lazy loading
- Device-specific resolution
You don’t need to worry about hosting. However, if the remote server is slow, your page may suffer. For better performance, use a fast CDN.


Tips for Image Optimization in Next.js
To fully benefit from Next.js image features, follow these tips:
1. Always Specify Dimensions
This prevents layout shifts. If the image is responsive, use layout="responsive" or fill.
2. Use Modern Formats
Next.js delivers WebP or AVIF automatically when possible. You don’t need to convert manually.
3. Lazy Load Below-the-Fold Images
Let Next.js handle it. By default, images load only when visible.
<Image src="/team.jpg" alt="Team" width={300} height={300} />No need to add lazy logic yourself.
4. Use Priority for Images
Above-the-fold images should load quickly. Set priority={true}.
<Image
src="/hero.jpg"
alt="Image"
width={1200}
height={600}
priority
/>5. Use Blurred Placeholders
For smoother UX, use placeholder="blur" with local images.
<Image
src={myImage}
alt="Blurred"
width={600}
height={400}
placeholder="blur"
/>For remote images, you must manually provide a base64 blur placeholder.
What’s New in Next.js?
Next.js improves performance and flexibility. Here are some image-related updates:
- Better AVIF support: It now supports newer image formats more consistently.
- Improved
remotePatterns: Matching rules are more flexible. - Edge compatibility: Image optimization works on edge runtimes using new strategies.
- Fewer warnings: Next.js improves developer feedback on misconfigured image paths.
These changes simplify image handling, especially for dynamic sites.
Conclusion
Image optimization is crucial for performance. Next.js makes this task easier than ever. Whether you’re serving local files or pulling from remote URLs, the built-in <Image /> component handles it all.
To summarize:
- Use
Imageinstead ofimgtags. - Declare dimensions to avoid layout issues.
- Configure remote image domains in
next.config.js. - Let Next.js handle lazy loading and format conversion.
This article was originally published on Medium.



