A hero image at 2400px wide looks sharp on a 27-inch retina display. The same file lands on a phone at 375px viewport, where it wastes bandwidth and slows the page. The visitor downloads 2MB when 200KB would look identical on their screen.
The srcset and sizes attributes solve this. You hand the browser several versions of the image, plus a hint about how wide it will display, and the browser picks the right one for the device.
This is not optional optimization. Images make up roughly 50% of total page weight on the average site. Oversized images are the most common cause of poor Largest Contentful Paint (LCP) scores, which feed directly into both user experience and search ranking.
Understanding srcset and sizes
The srcset attribute provides the browser with a list of image sources and their widths. The sizes attribute tells the browser how wide the image will be displayed at different viewport sizes. Together, they give the browser enough information to choose the right image.
`html
`
Breaking this down:
srcsetlists five image files with their intrinsic widths (400px, 800px, etc.)sizestells the browser: on screens up to 640px wide, the image takes 100% of the viewport; up to 1024px, it takes 50%; above that, 33%- The browser multiplies the display size by the device pixel ratio to determine which image to download
- A phone at 375px width with 2x retina display calculates: 375px * 2 = 750px needed, so it downloads
photo-800.jpg - A desktop at 1440px width with 1x display calculates: 1440px * 0.33 = 475px needed, so it downloads
photo-800.jpg
The src attribute serves as a fallback for browsers that do not support srcset, though all modern browsers do.
Prepare your image variants with the Image Resizer. Generate sizes at 400, 800, 1200, 1600, and 2400 pixels wide to cover the full range of devices.

Choosing the Right Image Breakpoints
Not every image needs five or six variants. The right number depends on how much the image size varies across viewports and how sensitive the image is to quality degradation.
A practical approach for choosing breakpoints:
- Start with the maximum display width of the image (e.g., 1200px on a wide desktop layout)
- Multiply by 2 for retina: 2400px is your largest variant
- Work down: 1600px, 1200px, 800px, 400px
- Check the file size difference between adjacent variants. If two variants are within 20KB of each other, remove the smaller one. The browser saves no meaningful bandwidth by choosing it.
For hero images and full-width photos: 5 to 6 variants (400w through 2400w) For half-width content images: 3 to 4 variants (400w through 1600w) For thumbnail images: 2 variants (200w and 400w)
The diminishing returns point is important. Going from a 2400px image to a 1200px image on a device that only needs 1200px saves hundreds of kilobytes. Going from a 500px image to a 400px image saves maybe 15KB. Optimize where the savings are largest.
Compress each variant with the Image Compressor before deployment. A well-compressed 1200px JPEG is often smaller than an uncompressed 800px version.
Not every image needs five or six variants.
The picture Element for Art Direction
The element goes beyond resolution switching. It lets you serve completely different images based on viewport size, which is called art direction.
`html
`
Why use different images instead of the same image at different sizes? Because a wide landscape photo that looks great on desktop might show the subject too small on a phone. A cropped, tighter version that focuses on the main subject works better on small screens.
Art direction is also how you serve different image formats:
`html
`
The browser picks the first format it supports. AVIF offers the best compression, WebP is widely supported, and JPEG is the universal fallback.
Convert your images to modern formats with the Image Converter. AVIF files are typically 30 to 50% smaller than equivalent JPEG files, and WebP is 25 to 35% smaller.
Common Mistakes and Performance Pitfalls
Missing the sizes attribute: if you provide srcset without sizes, the browser defaults to sizes="100vw" and may download a larger image than necessary. Always specify sizes when using width descriptors.
Wrong sizes values: the sizes attribute must reflect how wide the image actually appears at each breakpoint. If your CSS makes the image 50% of the container and the container is 80% of the viewport, the sizes value should be approximately 40vw, not 50vw or 100vw.
Not accounting for CSS padding and margins: if your image is in a container with 20px padding on each side, the image is 40px narrower than the container. Factor this into your sizes calculation.
Too many variants: each additional image variant consumes storage, CDN bandwidth, and build pipeline time. Five variants cover most cases. Ten is overkill for all but the most image-heavy sites.
Forgetting lazy loading: images below the fold should have loading="lazy" to defer loading until the user scrolls near them. But never lazy-load your LCP image (usually the hero image). That should load immediately with loading="eager" or fetchpriority="high".
Not setting width and height: always include width and height attributes on img elements to prevent layout shift (CLS). The browser uses these to calculate the aspect ratio and reserve space before the image loads.
`html
`
**Missing the sizes attribute**: if you provide `srcset` without `sizes`, the browser defaults to `sizes="100vw"` and may download a larger image than necessary.
Testing and Validating Responsive Images
Verifying that the browser is actually downloading the correct image variant requires some investigation.
Chrome DevTools Network tab: filter by "Img" to see which image files were downloaded. Check the file names to verify the right variant was selected. Switch between device emulation sizes and reload to see different variants load.
Lighthouse audit: the "Properly size images" audit flags images where the downloaded file is significantly larger than the display size. Aim for zero flags.
Chrome DevTools Elements panel: hover over the element and check the "Rendered size" versus "Intrinsic size" in the tooltip. If the intrinsic size is more than 2x the rendered size, you are serving an image that is too large.
RespImageLint bookmarklet: a browser bookmarklet that analyzes all images on the page and reports issues with srcset, sizes, and format selection. It catches mistakes that manual inspection misses.
For automated checking, consider adding image optimization to your build pipeline. Tools like sharp, squoosh, and next/image (for Next.js) can generate responsive image variants automatically during the build process, eliminating manual image preparation.
The key metric to track is total page weight on mobile. A well-optimized page with responsive images typically weighs 500KB to 1.5MB on mobile. If your page exceeds 3MB, images are almost certainly the culprit.

FAQ
Do I need srcset for every image on my page?
No. Focus on images that are large (hero images, feature images, product photos) and images that vary significantly in display size across breakpoints. Small icons, logos, and thumbnails under 10KB do not benefit meaningfully from srcset.
What image formats should I use with srcset?
Use AVIF as your primary format (best compression), WebP as a fallback (broad support), and JPEG as the universal fallback. Use the element with tags to serve different formats. For icons and illustrations, SVG is the best choice because it scales to any resolution without multiple variants.
Does Next.js handle responsive images automatically?
Yes. The Next.js component generates multiple image sizes, serves modern formats (WebP by default), and handles lazy loading automatically. However, you still need to provide a meaningful sizes prop to get optimal results. The default sizes="100vw" is often too generous.
How do CDNs help with responsive images?
Image CDNs like Cloudinary, Imgix, and Cloudflare Images can transform images on the fly. Instead of generating multiple variants at build time, you request a specific size through URL parameters and the CDN generates and caches it. This simplifies your workflow but adds a service dependency and cost.
### Do I need srcset for every image on my page.
Markdown Table Generator: Build Clean Tables Without the Pain
Markdown tables are simple until the pipes and dashes stop lining up. Learn the syntax, alignment tricks, and a free tool that formats tables for you.
CSV to JSON: Convert Spreadsheet Data for APIs and Code
Turn a CSV export into clean JSON for APIs, imports, and scripts. Learn how the conversion works, common pitfalls with types and quotes, and a free tool.
JSON Guide: Format, Validate, and Convert JSON Files
JSON guide for developers: syntax rules, common parse errors, formatting and schema validation, plus how to convert between JSON and CSV files.
