How Image Size Affects Your Website Speed

If your site feels slow, images are the first place to look. On most websites they account for more total page weight than every other asset combined — HTML, CSS and JavaScript included. That also makes them the highest-leverage thing you can fix: a handful of well-compressed images can shave seconds off a page load that a dozen small code tweaks wouldn't touch.

Where images actually hurt

Google's Core Web Vitals are the speed metrics that feed into search ranking. There are three, and images bear directly on two:

Metric"Good" thresholdDo images affect it?
Largest Contentful Paint (LCP)under 2.5 sDirectly, and usually decisively
Cumulative Layout Shift (CLS)under 0.1Yes, but through markup rather than weight
Interaction to Next Paint (INP)under 200 msOnly indirectly

LCP measures how long the biggest visible element takes to render. On most pages that element is an image — a hero banner, a product shot, a post's header. A heavy image is the single most common cause of a failing LCP.

CLS measures how much the layout jumps while loading. This isn't about file size at all: it happens when an image arrives without its dimensions declared, so the browser only learns how much room it needs after everything else has already been positioned.

INP measures responsiveness to input, and images touch it only at the margins — a very large image still costs main-thread time to decode, which can delay a tap response while it happens.

One detail that saves a lot of confusion: Google grades these on the 75th percentile of real users over a rolling 28-day window, via the Chrome User Experience Report. You pass only when at least 75% of actual page views clear the threshold. This is why a perfect Lighthouse score and a failing Search Console report can coexist quite happily — more on that below.

What a megabyte actually costs in seconds

This is the part that makes the trade-off concrete. Lighthouse's default mobile profile throttles to 1.6 Mbps with 150 ms of latency — a deliberately unglamorous connection, roughly the bottom quarter of 4G. At that speed you get about 195 KB per second.

Take the JPG quality curve we measured in how to compress without losing quality and convert the file sizes into transfer time:

QualityFile sizeTransfer time at 1.6 Mbps
1001220 KB6.25 s
95402 KB2.06 s
90234 KB1.20 s
85151 KB0.77 s
80118 KB0.60 s
7075 KB0.38 s

Now set that against a 2.5-second LCP budget — and remember the budget has to cover everything, not just the image: DNS, connection setup, server response, HTML parsing, CSS, and only then the image download.

At quality 100, the image alone overruns the entire budget by nearly four seconds. At 95 it consumes over 80% of it. At 85 it takes under a third and leaves real room for everything else. That's the same one-step-from-100-to-95 saving from the compression article, restated as the difference between passing and failing.

Two caveats so the numbers stay honest. Our test image is grain-heavy, so its absolute sizes run higher than a typical phone photo — the ratios transfer, the bytes are illustrative. And a real connection isn't a steady pipe: the image usually can't even start downloading until the HTML has been parsed, which makes the practical picture slightly worse than the table, not better.

Which gives you a page weight budget

Turn that arithmetic around and it becomes a number you can actually design against. At 195 KB per second, a 2.5-second LCP budget buys you roughly 490 KB in total — and that total covers the HTML, the CSS, any blocking JavaScript, and the fonts, before a single image byte is spent.

Say the page shell costs 150 KB. You have about 340 KB left for whatever renders above the fold. One hero image at quality 85 (151 KB in our table) fits comfortably. Three of them do not.

This is also the answer to "how many images is too many". A gallery page with ten photos at 118 KB each is 1.18 MB — six seconds of transfer on that connection, before anything else loads. The fix isn't to compress each one harder; it's to load two and lazy-load the other eight, so only what's visible competes for the budget.

Two things buy back headroom outside the budget entirely. Caching means returning visitors pay nothing for images they already have, so set long Cache-Control lifetimes on files whose URLs change when the content does. And a CDN shortens the round trip rather than the payload — that 150 ms of latency is per request, and it is paid on every one of them.

The order that matters

Three levers, and they are not equally powerful. Pull them in this order:

  1. Resize to the real display size. A 4000-pixel-wide photo in a 600-pixel column downloads all 4000 pixels' worth of data so the browser can throw most of it away. No compression setting recovers that. This is the biggest single win and the one most often skipped.
  2. Switch format. WebP typically lands 25–35% below an equivalent JPG at the same visual quality, and AVIF further still. Both are safe to display in every browser still receiving updates. (WebP vs JPG vs PNG vs AVIF covers the trade-offs.)
  3. Then set quality. By this point you're optimising an already-reasonable file, which is exactly the right time to do it.

Four delivery mistakes that undo good compression

You can compress perfectly and still fail LCP. These are the ways.

Lazy-loading the hero image. The most common own-goal in this whole list. loading="lazy" tells the browser the image isn't urgent — so applying it to your LCP image actively delays the thing being measured. Lazy-load what's below the fold; never lazy-load what's above it.

Not declaring dimensions. Always set width and height (or a CSS aspect-ratio). The browser then reserves the correct space before the file arrives, and CLS stops happening. Costs nothing, fixes an entire metric.

Serving one size to every device. A phone gets the same 2000-pixel file as a desktop. srcset with sizes lets the browser pick:

<img
  src="hero-800.jpg"
  srcset="hero-400.jpg 400w, hero-800.jpg 800w, hero-1600.jpg 1600w"
  sizes="(max-width: 600px) 100vw, 800px"
  width="800" height="500"
  alt="…"
  fetchpriority="high"
/>

That fetchpriority="high" is the counterpart to the lazy-loading mistake: it tells the browser to fetch this one first, ahead of the other images it discovered at the same time.

Not offering modern formats with a fallback. <picture> lets you serve AVIF to what supports it and fall back cleanly:

<picture>
  <source srcset="photo.avif" type="image/avif" />
  <source srcset="photo.webp" type="image/webp" />
  <img src="photo.jpg" width="800" height="500" alt="…" />
</picture>

The browser takes the first type it understands. Nothing breaks anywhere.

Lab numbers vs real users

Worth understanding before you chase a score. Lighthouse and PageSpeed Insights run a lab test: one load, one simulated device, one throttled connection. Deterministic and useful for finding problems.

Search Console's Core Web Vitals report shows field data — actual visitors, real devices, real networks, aggregated at the 75th percentile over 28 days. Different question, different answer.

Two practical consequences. A lab score improves the moment you deploy a fix; the field report takes weeks to catch up, because it's still averaging in the old experience. And a lab test on your laptop's fibre connection tells you very little about a visitor on a bad mobile connection — which is precisely who the 75th percentile is measuring.

Use the lab test to find what's wrong. Use the field data to decide whether it's actually fixed.

How to check where you stand

Run the page through PageSpeed Insights. It reports both lab and field data side by side for any public URL, and names the specific element it chose as your LCP — which is usually the fastest way to discover that the image you thought was the problem isn't the one being measured.

Doing the compression part right

The most common mistake here isn't skipping compression, it's reaching for a tool that uploads your images to somebody else's server to do the work. That's slower, and it leaves a copy of your possibly-unpublished content somewhere outside your control while it processes.

img-compress handles steps 2 and 3 from the list above — compressing and converting between JPG, PNG, WebP and AVIF, entirely on your own device, HEIC photos from an iPhone included, with a single hero image finishing as readily as a full batch of product shots before a launch.

Step 1, resizing, it deliberately does not do: it re-encodes without changing dimensions, because the right dimensions depend on where the image is going. That part belongs in your image editor or CMS. And the delivery attributes above belong in your templates — no compressor can add them for you.