Web Performance Optimization: What Core Web Vitals Actually Measure and How to Fix Them
Google's 2021 page experience update made Core Web Vitals a ranking signal. Since then, LCP (Largest Contentful Paint), INP (Interaction to Next Paint), and CLS (Cumulative Layout Shift) have become the most-watched frontend metrics. But most optimization guides stop at 'compress your images.' The LCP on your product page is probably your hero image — but the reason it loads slowly might be your render-blocking CSS, not the image size.
Key Takeaways
- Core Web Vitals are measured at P75 — the 75th percentile of your actual visitors' experience, not an average or best-case
- LCP is almost always an image — preload your LCP element with
<link rel="preload" as="image">and eliminate render-blocking resources - INP replaced FID in March 2024 — measures all interactions, not just the first; long JavaScript tasks are the primary cause of poor INP
- CLS is caused by images without dimensions and late-loading content — always set width/height on images, reserve space for ads and embeds
- Bundle splitting cuts initial JS payload — route-based code splitting ensures users only download code for the page they're on
LCP: Usually an Image, Sometimes a Heading
LCP identifies the largest element that's visible in the viewport when the page first loads — typically your hero image, product photo, or large H1 heading. The element itself is usually not the problem; the problem is what delays it from loading. Common culprits, in order of frequency:
| LCP Delay Cause | Why It Delays LCP | Fix |
|---|---|---|
| Render-blocking CSS | Browser won't paint until CSS loaded | Move critical CSS inline; defer non-critical |
| Render-blocking JS | Scripts with no async/defer block parse | Add defer/async to third-party scripts |
| LCP image not preloaded | Discovery delayed in HTML parse order | Add rel=preload to the LCP image link tag |
| Image too large (file size) | Download takes too long | Convert to WebP/AVIF, compress, serve via CDN |
| Slow server response (TTFB) | Everything waits for first byte | CDN, server-side caching, edge functions |
| Client-side rendering (CSR) apps | DOM built by JS, not HTML | SSR or SSG — serve pre-rendered HTML |
INP: Breaking Up Long Tasks
INP measures the time from a user interaction (click, key press, tap) to when the browser renders the visual response. A long task on the main thread (any JavaScript execution over 50ms) blocks this response. The fix is yielding to the browser between work chunks using setTimeout(callback, 0), scheduler.yield() (Chrome 124+), or moving heavy computation to a Web Worker.
Breaking Up a Long Task to Improve INP:
Image Optimization Tools
Image & Developer Tools
Image format converter (JPEG/WebP/PNG), color picker, SSL checker, and other web developer utilities to help improve your site's Core Web Vitals.
Open Developer Tools →