Image weight is slowing your page down
HTTP Archive data shows a typical mobile page weighs over 2.6 MB, and more than two-thirds of that is images. Trimming image bytes is one of the most direct performance wins available, and the first step is stopping the habit of shipping files larger than the space they occupy on screen.
Save for the container, not the source
Two images can look identical at 300 pixels wide while one file is over ten times larger than the other. The difference: one was saved at a resolution far beyond its display size. For any image with a fixed display width, save the file at that same width. This is the simplest possible optimization—zero code changes, instant savings.
When layouts are fluid, the browser needs help
Fixed widths are the exception. Images sit inside responsive grids, stretch with percentage widths, and serve devices with dense pixel ratios. Uploading a single size forces a compromise between quality on large screens and wasted bytes on small ones.
The browser would ideally fetch the smallest file that still looks sharp, but it cannot know an image’s real width without downloading it. That is the catch-22 srcset solves. Provide multiple saved sizes and annotate each one with its pixel width:
<img src="small.jpg" srcset="small.jpg 500w, medium.jpg 1000w, large.jpg 1500w">
The w value (e.g. small.jpg 500w) tells the browser that small.jpg is 500 pixels wide. The browser can now pick the smallest suitable file based on the viewport and the device’s pixel density, without downloading candidates to measure them.
Generating multiple sizes
Manual resizing works for a handful of hero images, but product catalogs need automation. Two practical routes exist:
- Build-time processing: add image resizing to your build pipeline using a tool like Imagemin.
- Image services: upload high-resolution originals and let a service handle resizing and delivery. Commercial options include Cloudinary; Thumbor is a self-hosted open-source alternative. These services accept URL parameters to control output dimensions and can automatically deliver WebP to browsers that support it without changing the file extension.
Refining the choice with sizes
Without further hints, the browser assumes an srcset image occupies the full viewport width. The sizes attribute tells it the actual rendered width before layout runs:
<img src="small.jpg" srcset="small.jpg 500w, medium.jpg 1000w" sizes="50vw">
Here, sizes="50vw" signals the image will be displayed at half the viewport, allowing the browser to pick a smaller file than it would otherwise.
Dealing with cropping and pixel density
srcset assumes the same image content at different scales. When the crop itself must change—a wide hero that becomes a square card on mobile—use the <picture> element for art direction instead.
High-end phones pack two or three times as many physical pixels per row, which changes the file dimensions you need to supply. Density descriptors, covered in dedicated guides on responsive images, handle this scenario alongside srcset.
Browser support and graceful fallback
srcset and sizes are supported by over 90% of browsers globally. Browsers that lack support simply fall back to the src attribute, making these attributes a progressive enhancement with no downside for older clients.



