Core Web Vitals

Why Are Your Core Web Vitals Failing Even Though the Page "Feels" Fast?

Core Web Vitals are Google's three metrics, measured in the field, for the loading and responsiveness experience of real users: Largest Contentful Paint (LCP), Interaction to Next Paint (INP), and Cumulative Layout Shift (CLS). Fixing them means diagnosing against real Chrome User Experience Report (CrUX) field data, not just a single Lighthouse lab run, and tracing each failing metric to its actual root cause in the render and hydration path rather than applying generic performance advice.

Dfeelings Team · GEO & Website Development Company, Amman, Jordan
Last updated: September 18, 2026

The problem

Lab tools (Lighthouse, PageSpeed Insights' lab section) measure one simulated run on one device profile. That is useful for debugging, but not what Google actually uses to rank pages. The Core Web Vitals relevant to ranking are field data from CrUX, aggregated from real visitors' real devices and connections over a rolling 28 day window. A page can score well in a single lab run while failing INP in the real world because real users are on slower phones triggering more JS execution in the browser than the lab test simulated, or vice versa.

Symptoms

  • PageSpeed Insights shows a lab score in the 90s but the field data section ("Discover what your real users are experiencing") reports LCP or INP in the "Needs improvement" or "Poor" range, or shows "no data available" for a page with little traffic.

  • Search Console's Core Web Vitals report groups a set of URLs as "Poor" or "Needs improvement" by URL pattern, and the pattern correlates with a specific template or component, not the whole site.

  • LCP is dominated by a data fetch in the browser: the largest element only paints after an API response rendered by JS returns, instead of being present in the initial HTML.

  • INP degrades specifically during interaction (clicking a filter, opening a menu) on pages with heavy client state or animation libraries, even though the initial load felt fine.

  • CLS spikes are traced to web fonts swapping in after paint, images without explicit width and height, or content injected above elements that have already rendered (ads, banners, dynamically loaded widgets).

How we diagnose it

We start from Search Console's Core Web Vitals report and CrUX field data (via PageSpeed Insights or the CrUX API) grouped by URL pattern, so we're fixing what's actually failing for real visitors rather than chasing a lab score. For each failing group we pull a representative URL into Chrome DevTools' Performance panel and the Lighthouse trace to find the specific element and script responsible: the LCP element and what blocked its paint, the longest running scripts during interaction for INP, and the exact DOM mutation causing layout shift for CLS. On sites rendered with JavaScript we specifically check how much of the critical path is rendering and hydration in the browser, since that's the most common shared root cause across all three metrics.

The fix

LCP fixes typically mean getting the largest element above the fold (usually a hero image or heading) into the initial HTML rendered on the server instead of behind a client fetch, prioritizing that image's request (`fetchpriority="high"`, and not lazy loading it), and removing resources ahead of it that block rendering. INP fixes mean reducing the JavaScript that runs during and immediately after interaction: code splitting bundles that aren't critical, deferring scripts from third parties, and avoiding large synchronous state updates on every keystroke or scroll event. CLS fixes mean reserving space for images, embeds, and ads before they load (explicit dimensions or boxes with a fixed aspect ratio) and loading web fonts with a strategy that avoids a visible reflow when the font swaps.

Implementation details

On this Next.js site, LCP work leans on the framework's own primitives rather than generic advice: `next/image` for automatic sizing and priority hints on hero images, Server Components rendering primary content on the server so it's in the initial response rather than behind a client fetch, and the dynamic loader pattern (thin client wrappers around heavier interactive components, imported with `next/dynamic` and `ssr: true`) to split out sections heavy with animation so they don't block the initial paint or add to the main thread work counted toward INP. For CLS, image components carry explicit dimensions and animated sections use Framer Motion's `initial`/`animate` props against layout space reserved in advance rather than injecting content that shifts existing elements. We measure before and after with the same CrUX field data used for diagnosis, not just a fresh lab run.

Common mistakes

  • Optimizing against a single Lighthouse run and declaring victory, without checking whether field data from real users (CrUX) actually moved. Lab and field scores can diverge significantly.

  • Fixing LCP by simply compressing the hero image while the actual bottleneck is that the image's URL isn't known until a data fetch in the browser resolves.

  • Adding more JavaScript in the browser (a "performance monitoring" or "optimization" script) to fix a problem that JavaScript itself is causing, which can make INP worse.

  • Reserving space for CLS with a fixed pixel height that breaks on responsive layouts instead of a reservation based on aspect ratio that scales with viewport width.

  • Treating all three metrics as one "performance score" and applying a generic checklist instead of tracing each metric to its own specific root cause, which are often unrelated to each other.

Validation

We validate against Search Console's Core Web Vitals report over the following CrUX reporting window (results take up to 28 days to fully reflect in field data, so we also confirm the underlying lab metrics moved immediately as a leading indicator) and run PageSpeed Insights' field data section again to confirm that LCP, INP and CLS for real users crossed into "Good" thresholds, not just that the lab score improved.

Considerations for bilingual sites heavy on JavaScript

Core Web Vitals thresholds are the same across languages, but Arabic RTL layouts add their own CLS risk (logical vs. physical CSS properties, font loading for Arabic web fonts which are often heavier files than Latin fonts) that we check independently per locale rather than assuming results from the English locale transfer directly to the Arabic pages.

Related service & solutions

Core Web Vitals and JavaScript SEO frequently share the same root cause, heavy rendering in the browser, so a Core Web Vitals engagement and a JavaScript SEO audit are often the same diagnostic work viewed through two different metrics.

Frequently asked questions

Common questions about Core Web Vitals optimization

They're one signal among many, and Google has said content relevance matters more. But for pages that are otherwise similar in relevance, Core Web Vitals can be a tie breaker, and poor vitals also directly hurt conversion rate independent of rankings. That is why we treat it as worth fixing on its own merits, not only as an SEO tactic.
The lab score is one simulated test run on a fixed device and network profile. The field score (CrUX) aggregates real visitors on real devices and connections over 28 days. If your actual traffic skews toward slower phones or connections than the lab simulation, field scores can be worse than the lab score suggests, and that's the number that matters for ranking.
Whichever one Search Console's Core Web Vitals report shows as failing for the most URLs or the templates with the most traffic. There's no universal priority order, since it depends on where your specific pages are actually failing.
Yes. Adding a new script from a third party, an unoptimized image, or a new section rendered in the browser can regress a metric that was previously fixed. We recommend monitoring the Search Console report on an ongoing basis rather than treating it as a one time fix.

Want your Core Web Vitals diagnosed against real field data?

Request a Core Web Vitals audit