How Image Compression Improves Core Web Vitals
Images are the single largest factor in most websites' Core Web Vitals scores. Here's how compression, format choice, and proper sizing directly affect LCP, CLS, and INP.
Core Web Vitals are Google's three metrics for judging real-world page performance. They're a ranking signal, they show up in Search Console, and, more importantly, they're a reasonable proxy for whether your site actually feels fast.
For most sites, images are the largest single factor in your CWV scores. Not JavaScript, not CSS. Images. They're the heaviest thing the browser has to download and they're usually the biggest thing on the page.
This post explains exactly how image work affects each of the three vitals, with concrete actions.
The three metrics
- LCP, Largest Contentful Paint. Time until the largest visible element renders. For ~70% of pages, this is an image.
- CLS, Cumulative Layout Shift. How much the page jumps around as it loads. Images without dimensions are a primary cause.
- INP, Interaction to Next Paint. Latency on user interactions. Image work can block this if you're decoding huge images on the main thread.
Google's "good" thresholds:
- LCP under 2.5s
- CLS under 0.1
- INP under 200ms
How compression affects LCP
LCP is wall-clock time from navigation start to the moment the largest element finishes rendering. If your hero image is 800 KB, the browser has to download 800 KB before it can paint. If it's 200 KB, the browser only waits for 200 KB.
Three things you can do:
1. Pick a modern format. AVIF or WebP for hero images can cut size by 50โ80% over JPG with no visible quality loss. A 1.2 MB JPG becomes a 250 KB AVIF. On a typical 4G connection (5โ10 Mbps real-world), that's a 1.5-second LCP improvement on its own.
2. Resize, don't just compress. A 4000ร3000 image being shown in a 800-pixel slot is wasting 95% of its bytes. Generate the right size for the actual display. The HTML srcset attribute and the <picture> element let you serve different sizes for different viewports.
3. Get the LCP image into the initial HTML response. Don't lazy-load your hero image, don't load it with JavaScript, don't defer it. Use <link rel="preload" as="image" href="hero.webp"> if the browser doesn't already discover it fast enough. Lazy-loading is for below-the-fold images.
For a typical content page, applying just the format swap (JPG โ WebP at quality 80) on the hero image alone usually moves LCP by 800โ1500ms.
How image work affects CLS
Layout shift happens when the browser doesn't know how big an image will be until it loads, then has to push the rest of the page down once it knows.
The fix is one HTML attribute: always include width and height.
<img src="photo.webp" alt="..." width="1200" height="800">
The browser uses these to reserve space before the image arrives. The image still loads at responsive sizes via CSS, but the aspect ratio is locked in from the start. Zero shift.
This costs nothing. Any CLS improvement here is a free win.
How decoding affects INP
INP measures interaction latency. If a click triggers code that decodes a large image on the main thread, INP suffers: the main thread can't process input until decoding finishes.
Two things help:
1. Smaller images decode faster. A 200 KB AVIF decodes in ~30ms. A 4 MB PNG decodes in ~250ms. If image decoding is happening during interactions, the difference is felt directly.
2. Use decoding="async" on images that aren't above the fold. This lets the browser decode them off the main thread.
<img src="photo.webp" alt="..." decoding="async" loading="lazy">
loading="lazy" defers the network request until the image scrolls near the viewport. Combined with async decoding, off-screen images stop competing with interactions.
Order of operations for a real audit
If you're trying to fix a poor CWV score on a real site, here's the order I'd recommend:
- Find your LCP element. Open DevTools โ Performance โ record a load. The "Largest Contentful Paint" event tells you exactly what painted last.
- If it's an image, check its size. Run it through a compressor. If it's a JPG above 200 KB on a hero, there's a clear win available.
- Convert it to AVIF or WebP. AVIF for hero images, WebP for everything else.
- Resize it to the actual rendered dimensions (use
srcsetorsizesfor responsive layouts). - Add
widthandheightattributes to all<img>tags. CLS often drops to near zero from this single change. - Set
loading="lazy" decoding="async"on every below-the-fold image. - Re-measure. A real audit usually moves LCP by 1โ3 seconds and CLS to under 0.05 if images were the problem.
What this looks like in numbers
A real e-commerce category page we measured:
- Before: LCP 4.2s, CLS 0.18 (poor on both)
- Hero JPG (640 KB) converted to AVIF at quality 60: 95 KB
- Product thumbnails (PNG, ~120 KB each) converted to WebP q85: ~28 KB each
- Added width/height attributes to 47 images.
- After: LCP 1.9s, CLS 0.04 (good on both)
Total work: about an hour. No code changes beyond image processing and one templating tweak.
What compression alone can't fix
A few things will still hurt your scores even with perfect image work:
- Render-blocking JavaScript that delays first paint.
- Slow hosting that takes 600ms to return the HTML.
- Bloated CSS that takes longer to parse than your image takes to download.
But: for a typical content site or e-commerce store, image work is the highest-leverage thing you can do. It's almost always the cheapest path to a "Good" score across all three metrics.
You can compress images directly in your browser with OmegaPix's Image Compressor, convert to AVIF, or batch-convert PNGs to WebP. Files never leave your device, and the encoders are the same ones browsers use natively.
Try Image Compressor, free in your browser
No uploads, no account. Your images never leave your device.
Open Image Compressor