Insights · What the free audit finds · 7 minutes
Phones Download Your Desktop Images
Why a 2.6 MB hero reaches a phone that needs 33 KB, how srcset and sizes let the browser choose, when you actually need the picture element, what WebP buys you, and where WordPress themes quietly undo the work it already does for you.
What is actually happening
On one site we audited this month, the homepage hero was a 1920 by 1080 WebP weighing 2.6 MB. On a phone, that image displays about 390 pixels wide. The phone downloads all 2.6 MB, decodes two million pixels, and then paints roughly 4% of them.
The same picture, resized to the 800 pixels a high-density phone actually uses, is 33 KB. Same photograph, same quality on that screen, 98% less to download. On a cellular connection that is the difference between the page appearing at once and a blank space for two or three seconds.
This is also why the score called Largest Contentful Paint suffers. The hero is usually the largest thing on the page, so the page does not feel loaded until the hero arrives, and the hero cannot arrive until every byte has.
Let the browser choose
The fix is not to make one smaller image. Desktop visitors still want the big one. The fix is to offer several sizes and let each browser pick. HTML has had the vocabulary for years: srcset lists the candidates and their widths, and sizes tells the browser how wide the image will be laid out, so it can do the arithmetic before downloading anything.
<img
src="/img/hero-1200.webp"
srcset="/img/hero-600.webp 600w,
/img/hero-900.webp 900w,
/img/hero-1200.webp 1200w,
/img/hero-1920.webp 1920w"
sizes="(max-width: 1020px) 100vw, 60vw"
width="1920" height="1080"
alt="Volunteers planting trees along the river trail"
fetchpriority="high"
/> Read sizes as a promise about layout: below 1020 pixels the image fills the viewport, above it the image takes 60% of the width. The browser multiplies by its own pixel density, picks the smallest candidate that is still sharp, and never downloads the rest. The width and height attributes reserve the space so the page does not jump when the image lands, which is what the score called Cumulative Layout Shift measures.
When you need the picture element
srcset handles one image at several sizes. The picture element handles two different problems. The first is art direction: a wide landscape crop on desktop and a tight portrait crop on a phone, because the same framing does not work at both shapes. The second is format fallback: offer AVIF to browsers that understand it, WebP to the rest, and a JPEG as the floor.
<picture>
<source media="(max-width: 700px)" type="image/avif" srcset="/img/hero-phone.avif" />
<source media="(max-width: 700px)" type="image/webp" srcset="/img/hero-phone.webp" />
<source type="image/avif" srcset="/img/hero-1200.avif 1200w, /img/hero-1920.avif 1920w" sizes="60vw" />
<source type="image/webp" srcset="/img/hero-1200.webp 1200w, /img/hero-1920.webp 1920w" sizes="60vw" />
<img src="/img/hero-1200.jpg" width="1920" height="1080" alt="Volunteers planting trees along the river trail" />
</picture> Most sites do not need this. If one crop works everywhere and you serve WebP, a plain img with srcset is the right tool, and it is far easier to keep correct. Reach for picture when you have a real art-direction problem or you are adding AVIF.
Formats: WebP now, AVIF when you can
WebP is supported by every browser your visitors use and is typically 25 to 35% smaller than a JPEG of the same visual quality. AVIF is smaller again but slower to encode, so it makes sense for the handful of images that matter most, with WebP behind it.
Format is not a substitute for size. The 2.6 MB hero above was already WebP. It was simply 1920 pixels wide and encoded at a quality nobody can see. Size first, then format, then quality.
Priority and laziness
Two attributes finish the job. The hero, the one image above the fold, gets fetchpriority="high" so the browser fetches it before the stylesheets and scripts that would otherwise queue ahead of it. Everything below the fold gets loading="lazy" so it is not downloaded until the visitor scrolls toward it.
The common mistake is applying loading="lazy" to the hero too, usually because a plugin adds it to every image. Lazy-loading the largest visible element makes the page slower, not faster, and Lighthouse will say so.
Where WordPress helps, and where themes undo it
WordPress has generated multiple sizes of every upload and written srcset and sizes into image tags automatically since version 4.4. Since 6.1 it can generate WebP alongside the original. For images placed through the editor, the work is done for you.
Heroes are where it goes wrong. Many themes and page builders (Elementor, WPBakery, and others) output the hero as a CSS background image, or reference the full-size original directly, and neither path carries a srcset. A hero set as a background image cannot be responsive in the way described here at all; it needs to become a real img, or the theme needs a mobile variant.
The other common leak is a plugin that strips or rewrites image tags, or a theme that requests the size named full for every thumbnail. The tell is the same in every case: view the page source, find the hero, and look for a srcset attribute. If it is not there, the browser has no choice to make.
Check your own site in a minute
Open your homepage on a phone, or in a desktop browser with the phone emulation turned on and the network panel open, filtered to images. Sort by size. If the top entry is over 300 KB, that image is the one to fix first. The free audit on this site runs the same check on your homepage and puts the largest image and its saving in plain English.
If you are a client, this is a small task under the retainer for a template hero, and a fixed-quote project if the whole media library needs re-encoding. Either way, open a request and we will start with the picture that costs the most.