The cheapest performance win nobody ships

Most sites lose more time to one unoptimized hero image than to any JS framework choice.

The cheapest performance win nobody ships

On most marketing sites, the single largest performance problem is one image. The hero sits at the top of the page, so it is almost always the Largest Contentful Paint element, and it is almost always shipped as a full-resolution JPEG or PNG with no responsive variants, no explicit dimensions, and no priority hint. Fixing it takes under an hour: convert to WebP or AVIF, generate a srcset so a 360px phone downloads a 360px file, set width and height so the browser reserves the space, add fetchpriority="high", and preload it. That sequence routinely removes more load time than a month of framework tuning, costs a fraction as much, and does not require anybody to agree on an architecture. It is the cheapest thing on the bill and it is still the thing most teams ship last.

Why is the hero image always the problem?

Because nothing else on a typical page combines size, position and priority the way the hero does. It is large by design, sits above the fold by definition, and is usually the one asset handed over by someone outside the engineering team altogether — a designer exporting at 2× for retina, or a client uploading straight from a phone camera through the CMS, with nobody in between checking what actually ships. The result is predictable: we audited the images across our own site recently and found 32 files over 100 KB, the largest a single JPEG at 868 KB, with zero WebP and zero srcset anywhere on the site. That is not an unusual state for a site that has otherwise been maintained carefully in every respect. Image weight is the failure mode that survives good engineering, because it enters through a door engineering does not guard, and nobody notices until someone measures it.

What does the fix actually look like?

The fix comes in order, because each step depends on the one before it, and skipping ahead usually means redoing work once a later step exposes what an earlier one assumed. Format and size decide how many bytes travel over the wire in the first place, so they have to be settled before anything else is worth touching. Reserving space is really a layout decision rather than a loading one, and it costs nothing to get right regardless of what happened earlier in the sequence. Priority is the step that actually depends on the other three being correct first, since a browser cannot fetch faster than the format allows or prioritise a resource whose layout it does not yet know. None of the four is difficult on its own — the entries below cover what each looks like in practice — but the order is the part most teams get wrong, treating a dependency chain as a list of parallel, interchangeable tasks.

Serve the right format. WebP is supported everywhere that matters and typically lands 25–35% smaller than an equivalent-quality JPEG. AVIF goes further again at the cost of slower encoding. Use <picture> with a JPEG fallback if you support anything unusual.

Serve the right size. This is the bigger mobile win and the one most often skipped. Without srcset, a phone downloads the desktop asset in full — the same 1200×800 file the 27-inch monitor gets. Generating three or four widths and letting the browser choose is a build-step change, not a redesign.

Reserve the space. Explicit width and height attributes let the browser compute the aspect ratio before the bytes arrive, which is what stops the page jumping as it loads. CSS still controls the rendered size; the attributes exist purely to prevent the shift.

Prioritise it. Mark the hero fetchpriority="high" and preload it. Equally important: do not mark it loading="lazy". Lazy-loading the LCP element is a common own goal — the attribute is correct for everything below the fold and actively harmful on the one image above it.

What do you measure, and in what order?

On every project we benchmark four numbers before touching anything: LCP, CLS, INP and TTFB. The order we attack them is almost always the same, image weight first, then late-loading JavaScript, then layout shift, then server latency, because that sequence runs from cheapest to most invasive, and because each earlier step changes the measurement of the ones that come after it, so fixing things out of order means re-measuring work you already did. Server latency comes last for a reason: a 1-second TTFB on a static file is worth fixing eventually, but it is usually a hosting or caching decision rather than a code one, and it is pointless to negotiate a CDN contract while the page is still shipping four megabytes of images nobody has compressed. Get the payload right first and you often discover the server was never the real constraint at all, just the last thing anyone thought to blame.

Does any of this survive the next six months?

Only if it is enforced somewhere, because good intentions do not survive contact with a CMS. An optimised hero is one deploy away from being replaced by a 4 MB upload, and the person who does it will have no idea they just undid a week of careful work, since nothing in the publishing flow tells them. Two things make it stick. First, an automated image pipeline — conversion, resizing and srcset generation handled at build time — so correctness is the default behaviour rather than a discipline somebody has to remember to apply on every upload. Second, a page-weight budget checked before release, with an actual number attached to it rather than a feeling about whether the page seems fast enough. If a change pushes a page past that ceiling, that becomes a conversation before launch instead of a mystery somebody has to diagnose three months later, once traffic has already been paying the cost.

Where does this sit against everything else?

It sits at the highest ratio of outcome to effort in front-end work, which is exactly why it is unsatisfying to put on a roadmap: there is no architecture decision to defend and nothing dramatic to announce, just a page that quietly paints in under two seconds instead of five, on the connection most of your audience is actually using rather than the one your laptop enjoys on office wi-fi. That makes it easy to skip in favour of work that sounds more strategic, even though almost nothing else moves conversion and cost-per-click as cheaply. If you want the fuller picture, the thresholds, what INP really measures, and how to keep the numbers from drifting once you have fixed them, that is the Core Web Vitals post. And if you want it done rather than explained, it lives inside our front-end development and web development work, and it is part of the technical groundwork in any SEO engagement we run.

← Back to all posts

Liked this piece?

Let's talk shop.

Got a project in mind? Let's talk.

Get in touch