How image compression improves LCP and Core Web Vitals

On most pages the largest element is an image, which makes image weight the single biggest lever on Largest Contentful Paint — and the markup around it the biggest lever on layout shift.

The thresholds

LCP — good
2.5 seconds or less. Images are usually the element being measured.
CLS — good
0.1 or less. Images without dimensions are the classic cause of failure.
INP — good
200 ms or less. Images affect this only indirectly, through decode work.
Measured at
The 75th percentile of real page loads, not a lab test.
Biggest LCP win
Fewer bytes in the hero image — resize before compressing.
Biggest CLS win
width and height on every image, always.
Most common own goal
Lazy-loading the hero image.

Fixing images for Core Web Vitals

  1. Step 1: Find out which element is actually your LCP

    Do not guess. Chrome DevTools' Performance panel and PageSpeed Insights both name the LCP element directly. It is usually a hero image, but it can be a heading or a block of text — and optimising the wrong element achieves nothing.

  2. Step 2: Cut the bytes in that one image

    Resize it to the largest size it is ever displayed at, doubled for high-density screens, then compress at quality 78–85. Going from 1.5 MB to 200 KB on the hero moves LCP far more than optimising thirty images below the fold.

  3. Step 3: Stop delaying it

    Remove loading="lazy" from the LCP image — lazy-loading the element your score depends on is the most common self-inflicted failure. Add fetchpriority="high" so the browser fetches it ahead of other resources, and preload it if it is discovered late, for example in CSS.

  4. Step 4: Reserve the space to stop layout shift

    Put width and height attributes on every image, or a CSS aspect-ratio. The browser then reserves the correct box before the file arrives, so nothing jumps as it loads. This is almost always the whole of a CLS problem.

  5. Step 5: Serve a modern format

    WebP is typically 25–35% smaller than JPEG at matched quality and supported by every current browser. That saving comes off the critical path directly, with no visual cost.

Understanding the metrics

What LCP actually measures

Largest Contentful Paint records when the largest text block or image in the viewport finishes rendering. It is a proxy for the moment the page looks useful, and Google treats 2.5 seconds or less as good, measured at the 75th percentile of real visits.

Because a hero image is usually the largest element, LCP is often just a measure of how quickly one image arrives and decodes. That breaks down into four parts: how long the server took to respond, how long before the browser discovered the image, how long it took to download, and how long to render it.

Compression attacks the third directly and the fourth slightly. Preloading and fetchpriority attack the second. If your problem is the first — a slow server — no amount of image work will fix it, which is why it is worth measuring before optimising.

Why lazy-loading the hero is so damaging

loading="lazy" tells the browser not to fetch an image until it approaches the viewport. For images further down a page this is genuinely valuable — most visitors never scroll to them.

Applied to the LCP image it is actively harmful. The browser deliberately delays the one request your score depends on, and the delay lands squarely in the metric. Blanket "lazy-load all images" advice, and plugins that apply it indiscriminately, cause this constantly.

The rule: lazy-load everything below the fold, never the hero.

CLS is almost entirely a markup problem

Cumulative Layout Shift measures how much visible content moves during loading. An image without declared dimensions occupies no space until it arrives, and then suddenly occupies a great deal — pushing everything below it down the page, often just as someone is reading or tapping.

Setting width and height fixes it completely. Modern browsers use those attributes to compute an aspect ratio and reserve the correct box before a single byte arrives, and CSS such as width: 100%; height: auto still scales the image responsively. You are not fixing the layout by adding them — you are giving the browser the ratio.

The same applies to anything that arrives late: adverts, embeds and web fonts all shift layout unless space is reserved for them.

Where images touch INP

Interaction to Next Paint, which replaced First Input Delay in 2024, measures responsiveness to user input, with 200 ms or less counting as good. Images affect it only indirectly.

Decoding a large image occupies the main thread, and a page decoding many at once can be slow to respond to a tap. Very large images make this worse, as do heavy JavaScript image galleries. Serving appropriately sized files is the fix — again, resolution rather than quality.

The order of operations that actually works

  1. Measure. Identify the LCP element and the largest requests. Field data beats lab data.
  2. Fix the one image that matters. Resize, compress, remove lazy loading, add fetchpriority="high".
  3. Add dimensions everywhere. This is cheap and usually resolves CLS outright.
  4. Lazy-load everything below the fold. Not before it.
  5. Convert to WebP. A free 25–35% once everything else is right.
  6. Then look at fonts, scripts and server response.

Most sites get the majority of their improvement from steps two and three alone.

Do it here instead

These run in your browser on any device, so nothing is uploaded and there is nothing to install.

  • Resize image

    By pixels or percentage, aspect ratio locked, across a whole batch.

    Open the tool
  • JPG to WebP

    Typically 25–35% smaller at matched quality. The standard web win.

    Open the tool
  • Compress to 200KB

    Full resolution kept, quality still invisible to the eye.

    Open the tool
  • Bulk compressor

    One setting across a whole folder, processed in parallel, downloaded as a ZIP.

    Open the tool

Questions

Frequently asked questions

Every answer below is present in the page source, expanded, so it can be read without opening anything.

Does compressing images improve Core Web Vitals?

It improves LCP directly, often substantially, because the largest element on most pages is an image and LCP largely measures how quickly it arrives. It does not improve CLS at all — that is fixed by declaring image dimensions, not by reducing bytes.

What is a good LCP score?

2.5 seconds or less counts as good, measured at the 75th percentile of real page loads. Between 2.5 and 4 seconds needs improvement, and above 4 seconds is poor.

Should I lazy-load all my images?

No. Lazy-load everything below the fold, and never the LCP image. Delaying the request for the very element your score is measured on is the most common self-inflicted Core Web Vitals failure, and blanket plugin settings cause it routinely.

How do I fix cumulative layout shift caused by images?

Add width and height attributes to every image, or set a CSS aspect-ratio. The browser then reserves the correct space before the file arrives, so nothing moves. This usually resolves an image-related CLS problem completely.

Does converting to WebP help my scores?

Yes, through LCP. WebP is typically 25–35% smaller than JPEG at matched visual quality, and those bytes come straight off the critical path. It is one of the few changes with a real benefit and no visual cost.

My images are optimised but LCP is still poor. Why?

The image is probably not your bottleneck. Check the LCP breakdown: a slow server response or a late discovery of the image both show up in the metric regardless of file size. Render-blocking CSS and JavaScript delay the whole paint, and a lazy-loaded or CSS-background hero is discovered late by definition.

From the blog

Related reading

More background from the blog.

  • Practical Guides

    How to Compress Images for a Website Without Wrecking Them

    Resize before you compress. Measured on one photograph: half the width at quality 80 produced a 16.4 KB file, while full width at quality 40 produced 20.6 KB and looked far worse. The order of operations matters more than the settings.

    8 min read

  • Image Formats

    WebP vs JPEG: Which Should You Use, and When JPEG Still Wins

    WebP produced a 27.0 KB file against MozJPEG's 41.1 KB on the same photograph at slightly higher measured fidelity — 34% smaller. It also produced a larger file than JPEG on random noise. The advantage is real and content-dependent.

    9 min read

  • Image Compression

    JPEG Quality Settings Explained: What the Number Actually Means

    Quality 80 is not 80% of anything. It is an index into a quantisation table. Measured on one photograph: dropping from 100 to 90 removes 77% of the file and 4.2 dB of fidelity; dropping from 40 to 30 removes 17% and costs almost as much.

    8 min read