Image Optimization with next/image
The next/image component wraps the standard HTML <img> tag with automatic optimization: it generates responsive srcset entries, lazy-loads images below the fold by default, serves modern formats like WebP or AVIF when the browser supports them, and prevents cumulative layout shift by reserving space based on declared width and height (or fill). Images are optimized on demand by Next.js's built-in image optimization API and cached, so the cost of resizing is paid once per unique size rather than on every request.
Cricket analogy: next/image reserving layout space via width and height is like a stadium pre-marking a player's exact position on the field before play starts, so nothing shifts unexpectedly once the ball is bowled, avoiding a chaotic 'layout shift' on the pitch.
Using the Image Component
For local images imported from the file system, Next.js infers width and height automatically from the file, so you often only need to pass src and alt. For remote images, you must specify width and height explicitly (or use fill with a sized parent container), and the remote domain must be allow-listed in next.config.js under images.remotePatterns for security — Next.js refuses to optimize arbitrary external URLs it hasn't been told to trust.
Cricket analogy: Requiring remote domains to be allow-listed is like a stadium only granting broadcast rights to specific approved networks (Star Sports, Willow TV) rather than letting any random channel stream footage without authorization.
import Image from 'next/image';
import heroPhoto from '@/public/hero.jpg'; // local import: dimensions auto-inferred
export default function Hero() {
return (
<div>
{/* Local image: no width/height needed */}
<Image src={heroPhoto} alt="Team celebrating a product launch" priority />
{/* Remote image: width/height required, domain must be allow-listed */}
<Image
src="https://images.example.com/team/avatar-42.jpg"
alt="User avatar"
width={96}
height={96}
/>
</div>
);
}
// next.config.js
module.exports = {
images: {
remotePatterns: [
{ protocol: 'https', hostname: 'images.example.com' },
],
},
};Use the priority prop on the single largest image visible above the fold (often the LCP element) to disable lazy loading and preload it, directly improving Largest Contentful Paint. Reserve it for one hero image per page — marking too many images as priority defeats the purpose.
Layout Behavior and the fill Prop
When an image's dimensions aren't known ahead of time — for example, a card grid where images should stretch to fill a variable-height container — use fill instead of width/height. The fill prop makes the image absolutely positioned to cover its nearest positioned ancestor, so that ancestor needs position: relative and explicit dimensions of its own; pair it with the sizes prop so the browser can pick the correctly sized source from the generated srcset rather than always downloading the largest variant.
Cricket analogy: Using fill to stretch an image into a variable container is like a boundary rope being adjusted per ground — Eden Gardens and the Chinnaswamy Stadium have different dimensions, but the rope always fills the available field edge.
If you use fill without giving the parent element position: relative (or another positioning context) and explicit width/height, the image can collapse to zero size or overflow unpredictably, since fill relies entirely on the nearest positioned ancestor for its dimensions.
- next/image auto-generates responsive srcset entries, lazy-loads by default, and serves modern formats like WebP/AVIF when supported.
- Local imported images get width and height inferred automatically from the file itself.
- Remote images require explicit width/height (or fill) and the domain must be allow-listed via images.remotePatterns in next.config.js.
- The priority prop should be used sparingly, on the single largest above-the-fold image to improve LCP.
- The fill prop makes an image absolutely fill its nearest positioned ancestor, requiring position: relative and defined dimensions on that parent.
- Pairing fill with the sizes prop helps the browser choose an appropriately sized image instead of always fetching the largest.
- Optimized images are cached per unique requested size, so the resize cost is paid once, not on every page view.
Practice what you learned
1. What must you configure in next.config.js before next/image can optimize an image from an external domain?
2. When should you use the `priority` prop on a next/image component?
3. What CSS requirement must the parent element satisfy for the `fill` prop to render correctly?
4. For a locally imported image (e.g., `import photo from './photo.jpg'`), which props does Next.js typically infer automatically?
5. What is the primary purpose of the `sizes` prop when used with `fill`?
Was this page helpful?
You May Also Like
Static Assets and the public Folder
How Next.js serves files from the public directory at the site root, and when to use it versus importing assets directly into components.
Font Optimization
How next/font automatically self-hosts and optimizes web fonts to eliminate layout shift and remove external network requests.
Styling Approaches in Next.js
A practical comparison of the main ways to style Next.js apps: global CSS, CSS Modules, Tailwind CSS, and CSS-in-JS with styled-jsx.
Related Reading
Related Study Notes in Web Development
Browse all study notesWebSockets Study Notes
Web Development · 30 topics
Web DevelopmentWebAssembly Study Notes
WebAssembly · 30 topics
Web DevelopmentgRPC Study Notes
Protocol Buffers · 30 topics
Web DevelopmentSpring Boot Study Notes
Java · 30 topics
Web DevelopmentFlask Study Notes
Python · 30 topics
Web DevelopmentDjango Study Notes
Python · 30 topics