Skip to content

Optimization

Image Compression for Core Web Vitals — What Actually Moves the Needle

The image optimization changes that actually improve LCP, CLS, and INP — with real numbers. Skip the myths, ship the ones that move scores.

Core Web Vitals are Google’s three measurements of real-world user experience, and images are tied up in all three of them. Largest Contentful Paint is almost always driven by a hero image. Cumulative Layout Shift is usually an image loading without reserved space. Interaction to Next Paint can be tanked by image decode work blocking the main thread. Fix the images and the scores move — often more than any other single optimization.

This guide covers what specifically moves the needle, with real numbers, not generic “optimize your images” advice.

The three vitals and the targets

For reference, the 2026 targets:

MetricWhat it measuresGoodNeeds ImprovementPoor
LCP (Largest Contentful Paint)Time to render the biggest visible element≤2.5s2.5-4s>4s
CLS (Cumulative Layout Shift)Visual stability during load≤0.10.1-0.25>0.25
INP (Interaction to Next Paint)Responsiveness to user input≤200ms200-500ms>500ms

INP replaced First Input Delay (FID) as a Core Web Vital in March 2024. If you’re reading older articles that mention FID, translate that to INP — it’s a stricter, more realistic measurement of interactivity.

LCP is almost always an image

Google’s field data consistently shows the LCP element on most web pages is an image — either a hero image, a product photo, or a featured blog image. Text elements are the LCP on maybe 20% of pages. So “optimize LCP” almost always means “optimize the LCP image.”

Three levers move LCP for image-driven pages:

1. Size the image correctly. The single biggest LCP win is shipping an image at the size it actually displays, not 4× larger. A hero that renders at 1200 px wide should not be a 4000 px JPG. Use Resize Image or a responsive image workflow to cap delivery dimensions.

A real example: a 4000×2667 hero at JPG 85 is 1.8 MB. The same hero at 1600×1067 (the max it’ll ever display on a desktop at 1.5× DPI) is 280 KB. That’s 6.4× less data over the wire. On a 4G connection at 5 Mbps, that’s roughly 2.9s vs 0.45s of transfer time — easily the difference between failing and passing LCP.

2. Use a modern format. At the same visible quality, WebP is 25-35% smaller than JPG and AVIF is 40-55% smaller than JPG. For a hero image, that’s directly LCP budget. See PNG to WebP or our format comparison guide for WebP vs AVIF in 2026.

3. Preload the LCP image. If your hero is discoverable only after a stylesheet or a JS bundle parses, the browser wastes time. A <link rel="preload" as="image" href="/hero.webp" fetchpriority="high"> in the <head> tells the browser to start fetching immediately.

In 2023, Chrome added the fetchpriority="high" attribute for <img> elements. Using it on your LCP image is a one-line change that commonly moves LCP by 100-400ms on slower connections.

CLS is almost always missing dimensions

The single most common cause of high CLS is images without reserved space. When an image loads and expands the page, everything below it jumps. Google counts that jump against you.

The fix is five years old: always set width and height attributes on <img> tags.

<!-- CLS-proof -->
<img src="/hero.webp" alt="..." width="1200" height="600">

Browsers use the width/height ratio to reserve space before the image loads. You can still style with CSS (max-width: 100%; height: auto;) — the attributes are aspect-ratio hints, not fixed dimensions.

For responsive images with srcset, the width/height should match the default src. The browser handles the rest.

For background images set via CSS, there’s no automatic aspect-ratio reservation. If you have a critical background image, set explicit min-height or use aspect-ratio: 16/9; on the container.

INP and decode cost

INP is the newest and least-discussed vital. It measures how responsive the page is to user input — a click, tap, or keypress — across the entire session, not just the first interaction.

Images affect INP in two ways:

Decode cost. Decoding a large JPG or PNG happens on the main thread by default. If you load a 6 MB image and the user taps a button while it’s decoding, that tap response waits. Shipping smaller images (via compression and correct sizing) reduces main-thread blocking time and improves INP indirectly.

Async decoding. The decoding="async" attribute on <img> tells the browser to decode the image off the main thread when possible.

<img src="/photo.webp" alt="..." width="800" height="600" loading="lazy" decoding="async">

Combined with loading="lazy" for below-the-fold images, this pattern is the 2026 default for non-LCP images. Don’t use loading="lazy" on your LCP image — lazy-loading the hero delays it and tanks LCP.

Quality settings that actually matter

A concrete example. Same 1600×1067 photograph, encoded at different JPG qualities:

  • Quality 95: 410 KB (virtually indistinguishable from original)
  • Quality 90: 260 KB (no visible loss at display size)
  • Quality 85: 180 KB (imperceptible unless you zoom in 200%+)
  • Quality 80: 135 KB (minor softening in gradients if you look for it)
  • Quality 75: 105 KB (visible chroma artifacts in smooth areas)
  • Quality 70: 85 KB (obvious artifacts, skin tones suffer first)

For photography on a content page, quality 82-85 is the sweet spot. That’s where the file size curve starts to flatten and further reductions start to visibly hurt. Quality 95 is wasteful for the web. Quality 70 is a false economy that makes you look cheap.

WebP quality scale is similar. AVIF quality scale is different — AVIF quality 60-65 produces visually similar output to JPG quality 82-85.

Use Compress Image to iterate through quality levels and see the file size for your specific image. Photo-heavy sites should settle on a quality per use case and stick to it; mixing quality 70 and quality 95 in the same gallery produces visible inconsistency.

Chroma subsampling, the underrated knob

JPG defaults to 4:2:0 chroma subsampling — the color channels are encoded at half resolution in both dimensions. For most photography this is invisible and saves ~40% of file size versus 4:4:4 (no subsampling).

Two cases where 4:2:0 hurts:

  1. Text rendered into an image. Screenshots, infographics with labels, any image where sharp colored text appears. 4:2:0 produces visible color fringing on text edges. Use 4:4:4 for these, or use PNG.
  2. Images with high-saturation color edges. Fine detail in reds and blues suffers more than greens because of how the YCbCr color space splits brightness from chroma.

Most compression tools default to 4:2:0 and expose a 4:4:4 option for these edge cases. If you’re compressing photography and the output looks soft or the text looks blurry, check the subsampling setting first.

The full pipeline checklist

To pass Core Web Vitals on an image-heavy page:

  • Ship the LCP image at the correct size (delivery size, not source size).
  • Use WebP or AVIF for the LCP image; JPG fallback in a <picture> tag.
  • Preload the LCP image with fetchpriority="high".
  • Set width and height on every <img>.
  • Use loading="lazy" and decoding="async" on below-the-fold images.
  • Compress at quality 82-85 for photography, 90+ for text-heavy images.
  • Reserve space for background images with explicit aspect-ratio CSS.
  • Avoid loading enormous images just to CSS-scale them down.

Do those seven things and LCP, CLS, and INP will all improve — often enough to move a page from “Poor” or “Needs Improvement” straight to “Good” without any framework changes or server work.

Related tools

Frequently asked questions

Does switching from JPG to WebP improve LCP?

Usually yes, and often significantly. At the same visible quality, WebP is 25-35% smaller than JPG, which directly cuts transfer time for the LCP image. For a hero image on a 4G connection, that can mean saving 200-500 ms off LCP. AVIF is 40-55% smaller than JPG and saves even more. Combine the format change with correct sizing and fetchpriority=high on the LCP image and it's common to move a page from Poor or Needs Improvement to Good without touching anything else.

What JPG quality setting is safe for product photos?

Quality 82-85 is the sweet spot for photography on a content page. At 85, file sizes are about 40% smaller than at 95 with imperceptible visible difference. Quality 75 starts showing chroma artifacts in smooth areas like skin tones and skies. Quality 70 is a false economy that looks cheap. For product shots where fine detail matters more, 85-90 is safer; for thumbnails, 75-80 is fine. Stick to one setting per use case across a gallery to avoid visible inconsistency.

When does loading=lazy hurt LCP?

When you put it on the LCP image itself. Lazy-loading defers the fetch until the image is near the viewport, so applying it to the hero or above-the-fold image delays the very thing LCP is measuring. Use loading=lazy only for below-the-fold images. For the LCP image, do the opposite: add fetchpriority=high to tell the browser to prioritize it, and consider a rel=preload hint in the head if the image is discovered late in the HTML.

Do I need width and height attributes if I use CSS to size images?

Yes — the attributes are what prevents Cumulative Layout Shift. Browsers use the width/height ratio to reserve layout space before the image loads. Without them, everything below the image jumps when it arrives, and Google counts that against you. You can still style with CSS (max-width: 100%; height: auto;) — the attributes act as aspect-ratio hints, not fixed sizes. For background images set via CSS, there's no automatic reservation; use aspect-ratio or explicit min-height on the container.

When should I use 4:4:4 chroma subsampling instead of the 4:2:0 default?

When the image contains sharp colored text — screenshots, infographics, labels overlaid on photos — or high-saturation edges in reds and blues. Default 4:2:0 encodes color channels at half resolution and produces visible color fringing on text edges. 4:4:4 preserves full color resolution at the cost of roughly 40% larger files. For ordinary photography, 4:2:0 is invisible and saves real bandwidth, so the choice only matters when text or saturated detail is in the frame.

Sponsored