The Core Web Vitals story is stable in 2026. The one real change came earlier: INP (Interaction to Next Paint) replaced FID (First Input Delay) as the responsiveness metric on 12 March 2024. INP is harder to pass because it looks at the interactions of a whole visit, not just the first one.
Here is what the three metrics measure, and how to fix each one.
INP: the interaction metric
FID measured the time between the user's first input and the browser starting to handle it. It was easy to pass by accident: if the first interaction happened after the page was idle, the score was always good.
INP fixes that. It observes the latency of the interactions across the visit (clicks, taps, key presses) and reports roughly the slowest one. On pages with many interactions it ignores one of the highest for every 50, so a single random hiccup does not decide the score (web.dev, "Interaction to Next Paint"). A page that feels quick on the first click but stutters when the user opens a menu scores badly on INP, where it would have passed on FID.
Targets, at the 75th percentile of page loads, mobile and desktop measured separately:
- Good: 200 ms or less.
- Needs improvement: more than 200 ms, up to 500 ms.
- Poor: more than 500 ms.
The fix is rarely about page weight. It is about long-running JavaScript on the main thread during input handling. Common culprits:
- Heavy click handlers that re-render large React subtrees. Fix by hoisting state, memoising children, or using
useTransitionto mark non-urgent updates. - Third-party scripts that interrupt during user interaction. Defer their loading or load them via
next/scriptwithstrategy="lazyOnload". - Layout thrashing inside scroll handlers. Use
requestAnimationFrameandIntersectionObserverinstead of measuring layout on every scroll event. - Synchronous local storage reads during input handling. Move them off the critical path with
useDeferredValueor just don't do them.
To measure INP in real users, not just lab conditions, use real user monitoring. The Chrome User Experience Report (CrUX) covers sites with enough traffic; for smaller sites, the web-vitals library plus any analytics backend captures the 75th percentile.
LCP: still 2.5 seconds
LCP (Largest Contentful Paint) is unchanged: 2.5 seconds or less at the 75th percentile to count as good (web.dev, "Largest Contentful Paint").
The LCP element on most pages is one of:
- The hero image. Make sure it has
priority(Next.js) orfetchpriority="high"(any framework), is served as AVIF or WebP, and is correctly sized for the viewport. - The main headline (a
<h1>). If your H1 is the LCP, the win is fonts. Self-host the font, subset it, preload the weight the headline uses, setfont-display: swap. - A hero video. Almost always the wrong choice for LCP. Put a real
<img>in front and let the video lazy-load behind it.
Three diagnostics that surface real LCP issues:
- Lighthouse on a throttled mobile profile. Not desktop. Not your laptop on home WiFi.
- WebPageTest from a test location near your audience, on a mobile connection profile.
- PageSpeed Insights, which shows the field data from CrUX for the last 28 days when your site has enough traffic.
CLS: still 0.1, mostly a discipline problem
CLS (Cumulative Layout Shift) is unchanged: 0.1 or less counts as good (web.dev, "Cumulative Layout Shift"). Most CLS comes from one of:
- Images without explicit width and height attributes.
- Ads or embeds (YouTube, social posts) loading after page render.
- Web fonts that swap visibly.
- Late-loading hero text that pushes everything else down.
Fixes are mechanical, not architectural:
- Set
widthandheighton every<img>and<video>. Useaspect-ratioin CSS for responsive images. - Reserve space for ads and embeds with a fixed-height container, even when empty.
- Match your font's metrics with the fallback font using
size-adjust,ascent-override, etc. Next.js does this for you when usingnext/font. - Avoid late-injected hero text. Render it server-side or with skeleton states.
What Google says about ranking
It is easy to find posts claiming Vitals got a heavier ranking weight or a new penalty. Google's own documentation says something more modest (Google Search Central, "Understanding page experience", updated 10 December 2025):
- Core Web Vitals are used by its ranking systems.
- There is no single page experience signal. The core ranking systems look at a variety of signals that align with overall page experience.
- Google always seeks to show the most relevant content, even if the page experience is sub-par. Where many pages are equally helpful, a great page experience can contribute to success.
In practice: fix Vitals because slow, jumpy pages lose visitors, and because they can matter when you and a competitor are otherwise close. Do not expect them to lift a page whose content does not answer the query.
What to fix first
Priority list, in order:
- Look at INP in real-user data. It is the metric a lab test on your own laptop is least likely to catch.
- Image delivery if a hero image is your LCP element.
- Font setup if your H1 is the LCP and the font swap is visible.
- A CLS pass on the pages with the most traffic.
- Long tasks on the main thread. Profile the busiest pages.
What this looks like with us
How we build treats speed as a build constraint rather than a later fix. We do not chase Lighthouse scores in isolation; we look at the real-user 75th percentile, because that is what the Core Web Vitals thresholds are defined on.
If you would rather have this built right from the start, the build is part of Startup, the one package we sell, with the price and the timeline published.