The key takeaway: WordPress has generated srcset and sizes attributes on every image automatically since version 4.4 — the problem on most sites isn't a missing feature, it's a wrong sizes value that quietly tells the browser to download a bigger file than the layout actually needs. Fixing that one attribute is usually the highest-leverage responsive-image change you can make.
What srcset and sizes Actually Do
A responsive <img> tag in WordPress looks something like this:
<img src="image-1024x683.jpg"
srcset="image-300x200.jpg 300w, image-768x512.jpg 768w, image-1024x683.jpg 1024w"
sizes="(max-width: 600px) 100vw, 600px">
srcset lists the available file candidates and their actual pixel widths. sizes tells the browser how wide the image will actually be displayed at different viewport widths. The browser combines both, along with the device's screen density, to pick the smallest file that will still look sharp — before it downloads anything.
This is the part worth underlining: the browser makes the decision, not WordPress and not a plugin. If sizes is accurate, the browser makes a good decision automatically. If sizes is wrong, the browser makes a confident, fast, and wrong decision — usually erring toward a larger file "just in case."
Where WordPress's Default Guess Breaks Down
WordPress calculates a default sizes value using a simple rule: assume the image displays at its own intrinsic width, up to the viewport width. That assumption holds for a simple single-column blog post. It breaks in a lot of common WordPress layouts:
- Grid and column layouts — a product grid showing 3 images per row displays each image at roughly a third of the container width, not the image's full intrinsic width.
- Page builder layouts — Elementor, Divi, and similar builders often set container widths via CSS that WordPress's PHP-side
sizescalculation has no visibility into. - Themes with a sidebar — the actual content column is narrower than the viewport, but the default calculation doesn't know that.
In each case, the browser is told "this image displays close to full viewport width," so it downloads a candidate sized for that — even though the image is rendered much smaller on screen.
How to Check If Your Site Has This Problem
- Open the page in Chrome, right-click a content image, and choose Inspect.
- In the Elements panel, find the
sizesattribute on the<img>tag. - Compare it to the image's actual rendered width — visible in the Computed panel as
width. - If
sizesclaims something close to the full viewport width but the image is rendered at, say, 33% of the container, the browser is very likely downloading a file 2-3x larger than necessary.
A quicker sanity check: open the Network tab, filter by Img, and compare the downloaded file's pixel dimensions (visible in the Preview tab) against its rendered CSS size. A large gap between the two is the signature of a broken sizes value.
Fixing the sizes Attribute
For most themes, this means overriding WordPress's default calculation with a value that matches your actual layout, using the wp_calculate_image_sizes filter:
add_filter('wp_calculate_image_sizes', function ($sizes, $size) {
return '(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw';
}, 10, 2);
The exact breakpoints should match your theme's actual CSS grid or container behavior — this example assumes a layout that shows one column on mobile, two on tablet, and three on desktop. Check your theme's stylesheet for the real breakpoints rather than guessing.
Registering the Right Image Sizes in the First Place
srcset can only offer candidates that actually exist. If your theme only registers a 1024px and a 300px thumbnail size, the browser has no 600px option to pick for a mid-size viewport — it has to choose the closest available one, which is still often oversized. Registering intermediate sizes with add_image_size() gives the browser more granular options:
| Size name | Width | Typical use |
|---|---|---|
| thumbnail | 150px | Admin lists, related-post cards |
| medium | 600px | Mobile content width |
| medium_large | 900px | Tablet content width |
| large | 1200px | Desktop content width |
| full | Original upload | Rarely the right choice to serve directly |
Registering a size doesn't regenerate it for images already uploaded — new sizes only apply going forward, or after running a regeneration tool on existing media.
A Concrete Example
On a recent audit of a WordPress blog using a 3-column related-posts grid, the default sizes attribute was claiming each thumbnail displayed at 100vw (full viewport width) on all screen sizes. In reality, each thumbnail rendered at roughly 320px on desktop.
| Before fix | After fix | |
|---|---|---|
| Candidate selected by browser | 1024px-wide file | 384px-wide file |
| Average file size per thumbnail | 145 KB | 38 KB |
| Total weight for a 6-thumbnail grid | 870 KB | 228 KB |
Correcting a single sizes filter cut roughly 640 KB from that one page — more than most image compression settings alone would achieve, because the problem wasn't compression, it was requesting a file four times larger than displayed.
Where Format Optimization Still Fits In
Getting srcset/sizes right controls which dimensions get downloaded. It doesn't control the format of those files. A correctly sized 384px JPEG is still larger than it needs to be if a 384px WebP or AVIF version would look identical at a smaller file size. This is where Erdo Image Optimizer fits in as a complementary fix, not a replacement: it converts every registered image size — including the smaller srcset candidates WordPress generates — to WebP and AVIF automatically, so the browser's correctly-sized pick is also served in the smallest usable format.
For more on the format side specifically, see our guide to converting WordPress images to WebP and our broader PageSpeed Insights checklist, which covers where responsive images fit into the bigger performance picture.
Further Reading
For the full technical specification behind how browsers evaluate srcset and sizes, web.dev's guide to responsive images is the most reliable reference — it covers density-based selection, art direction with the <picture> element, and edge cases this guide doesn't go into.
Wrapping Up
Responsive images in WordPress aren't broken by default — the mechanism has worked automatically since 2015. What breaks is the sizes value on layouts more complex than a single-column blog, quietly telling browsers to download files two or three times larger than what's actually displayed. Check the attribute against your real layout before assuming your responsive images are already working correctly, and pair the fix with format conversion for the full gain.