A practical guide to Core Web Vitals in 2026. Understand LCP, INP, and CLS, how to measure them, and the fixes that actually improve your scores.
Core Web Vitals have been a Google ranking factor since 2021, but the metrics have evolved — and many sites are still fighting battles against the old metrics while the new ones quietly drag their scores down. This guide covers where things stand in 2026, what each metric actually measures, and the specific technical fixes that move the needle.
Core Web Vitals are a set of user experience metrics that Google uses as a ranking signal. They measure real-world performance as experienced by actual users visiting your site — not lab scores from a single fast connection. Google collects this data through the Chrome User Experience Report (CrUX), which aggregates anonymised performance data from Chrome users.
For a URL to "pass" Core Web Vitals, 75% of its real-user sessions must fall within the "Good" threshold for all three metrics. This field data is what matters for rankings, not your Lighthouse score — though Lighthouse is useful for diagnosis.
The three current Core Web Vitals are:
LCP marks the point at which the largest visible element in the viewport has finished rendering. This is typically a hero image, a large heading, or a video thumbnail. It is the closest proxy to "when does the page feel loaded" that a single metric can offer.
Target: under 2.5 seconds
The LCP element is almost always one of:
<img> tag (hero image)<video> poster frameOpen Chrome DevTools, run a Lighthouse audit, and look at the "Largest Contentful Paint element" breakdown. The waterfall will show you where time is being spent: server response time, render-blocking resources, or the image download itself.
1. Preload your LCP image
<link rel="preload" as="image" href="/hero.webp" fetchpriority="high">
This tells the browser to fetch the image as early as possible, before it parses the full HTML.
2. Use fetchpriority="high" on the LCP image
<img src="/hero.webp" fetchpriority="high" alt="Hero image">
Do not lazy-load your LCP image. Lazy loading defers its fetch, directly harming LCP.
3. Serve images in modern formats
WebP is well-supported and typically 30–50% smaller than JPEG. AVIF is even more efficient where supported.
4. Reduce server response time (TTFB)
If your server is slow to respond, everything downstream is delayed. A CDN, server-side caching, and efficient database queries all help. Target TTFB under 600ms.
5. Eliminate render-blocking resources
CSS and synchronous JS in the <head> block rendering. Inline critical CSS and defer non-critical styles and scripts.
INP measures the latency of all user interactions with a page (clicks, taps, keyboard inputs) and reports the worst-case interaction over the page's lifetime. It replaced FID (First Input Delay) in March 2024.
The crucial distinction: FID only measured the delay before a browser started processing an input. INP measures the full cycle — from the interaction to the next visual update (paint). This makes it a far more honest measure of perceived responsiveness.
Target: under 200ms
INP problems are almost always caused by JavaScript — specifically, long tasks on the main thread that block the browser from responding to user input. Common sources:
In Chrome DevTools, use the Performance panel. Record a session interacting with your page and look for Long Tasks (shown in red, over 50ms). The Total Blocking Time (TBT) in Lighthouse is a lab proxy for INP.
The web-vitals JavaScript library can measure INP in the field:
import { onINP } from 'web-vitals';
onINP(console.log);
1. Break up long tasks
Use scheduler.yield() (or setTimeout as a fallback) to yield control back to the browser between chunks of work:
async function processLargeData(items) {
for (const item of items) {
process(item);
await scheduler.yield(); // yield to browser between items
}
}
2. Defer non-critical JavaScript
Use defer or async on script tags. Load third-party scripts (analytics, chat) after the page is interactive:
<script src="analytics.js" defer></script>
3. Audit your third-party scripts
Each third-party script is a potential INP liability. Use the Chrome DevTools "Third Party" filter in the Performance panel to see which scripts are causing long tasks. Lazy-load or remove those that are not essential.
4. Optimise React renders
If you are using React, use React.memo, useMemo, and useCallback to prevent unnecessary re-renders. Large lists should use virtualisation (react-window or similar).
5. Use a web worker for heavy computation
Move CPU-intensive tasks off the main thread entirely:
const worker = new Worker('heavy-computation.js');
worker.postMessage(data);
worker.onmessage = (e) => updateUI(e.data);
CLS measures how much the visible content of a page shifts unexpectedly during the user's visit. A score of 0 means nothing moved; higher scores represent more disruptive shifts. The classic experience: you are about to tap a button and an ad loads above it, pushing the button down.
Target: under 0.1
width and height attributes (browser does not know to reserve space)1. Always set width and height on images
<img src="photo.jpg" width="800" height="600" alt="...">
Even with responsive CSS (max-width: 100%; height: auto), providing dimensions lets the browser calculate the aspect ratio and reserve space.
2. Reserve space for ads and embeds
Use a fixed-size container for any dynamic content:
.ad-container {
min-height: 250px;
width: 300px;
}
3. Use font-display: optional or font-display: swap carefully
font-display: optional prevents FOUT entirely but may not show the custom font on first load. font-display: swap shows fallback immediately then swaps — preloading the font file reduces the swap time:
<link rel="preload" href="/fonts/main.woff2" as="font" type="font/woff2" crossorigin>
4. Avoid inserting content above existing content
If your cookie banner, notification bar, or live chat widget loads above the page content, it will cause a shift. Either reserve space for these elements or position them as overlays that do not affect document flow.
Google Search Console — the Core Web Vitals report shows field data aggregated for your site, broken down by mobile and desktop, with URL groups that have enough data.
PageSpeed Insights — shows both field data (CrUX) and lab data (Lighthouse) for individual URLs.
Chrome DevTools — essential for diagnosing the specific cause of a metric failure.
CrUX Dashboard (via Google Data Studio) — for tracking trends over time.
LCP, INP, and CLS each require different skills to fix — LCP is mostly about loading optimisation, INP about JavaScript performance, and CLS about layout stability. The site that consistently scores in the "Good" range for all three on mobile has put in genuine engineering effort, and that effort is rewarded both in rankings and in real user satisfaction.
Prioritise mobile field data over desktop, focus on INP if you have a JavaScript-heavy site, and treat Core Web Vitals as a continuous maintenance task rather than a one-time audit. The sites that stay in the "Good" range are the ones that have made it part of their development workflow.
Try Surfaceable
See how often ChatGPT, Claude, Gemini, and Perplexity mention your brand — and get a full technical SEO audit. Free to start.
Get started free →