Core Web Vitals
Why Are Your Core Web Vitals Failing Even Though the Page "Feels" Fast?
Core Web Vitals are Google's three field-measured metrics for real-user loading and responsiveness experience — 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.
The problem
Lab tools (Lighthouse, PageSpeed Insights' lab section) measure one simulated run on one device profile — useful for debugging, but not what Google actually uses to rank pages. Ranking-relevant Core Web Vitals 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 its real-world INP because real users are on slower phones triggering more client-side JS execution 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 low-traffic page.
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 client-side data fetch — the largest element only paints after a JS-rendered API response 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-side 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/height, or content injected above already-rendered elements (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 JavaScript-rendered sites we specifically check how much of the critical path is client-side rendering and hydration, since that's the most common shared root cause across all three metrics.
The fix
LCP fixes typically mean getting the largest above-the-fold element (usually a hero image or heading) into the initial server-rendered HTML instead of behind a client fetch, prioritizing that image's request (`fetchpriority="high"`, avoiding lazy-loading it), and removing render-blocking resources ahead of it. INP fixes mean reducing the JavaScript that runs during and immediately after interaction — code-splitting non-critical bundles, deferring third-party scripts, 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 aspect-ratio boxes) and loading web fonts with a strategy that avoids a visible swap-induced reflow.
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/priority hints on hero images, Server Components rendering primary content server-side so it's in the initial response rather than behind a client fetch, and the `dynamic-loaders` pattern (thin client wrappers around heavier interactive components, imported with `next/dynamic` and `ssr: true`) to code-split animation-heavy sections 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 already-reserved layout space rather than injecting content that shifts existing elements. We measure before and after with the same CrUX-backed field data used for diagnosis, not just a re-run lab score.
Common mistakes
Optimizing against a single Lighthouse run and declaring victory, without checking whether real-user field data (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 client-side data fetch resolves.
Adding more client-side JavaScript (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 an aspect-ratio-based reservation 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 re-run PageSpeed Insights' field data section to confirm real-user LCP, INP and CLS crossed into "Good" thresholds, not just that the lab score improved.
Considerations for JavaScript-heavy and bilingual sites
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 English-locale results transfer directly to the Arabic pages.
Related service & solutions
Core Web Vitals and JavaScript SEO frequently share the same root cause — heavy client-side rendering — 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
Are Core Web Vitals a major ranking factor?
Why does PageSpeed Insights show a good lab score but a bad field score?
Which metric should we prioritize first?
Can Core Web Vitals issues come back after a fix?
Want your Core Web Vitals diagnosed against real field data?
Request a Core Web Vitals auditYou Might Also Find Useful
How Long Does SEO Take to Work?
SEO takes 3–6 months to show results and 9–12 months for full ROI. Learn the honest timeline, what affects speed, and how to accelerate results in Jordan.
How Much Does SEO Cost? — Pricing Guide for Jordan & MENA
SEO in Jordan costs $500–$1,500/month for meaningful results. Learn what drives pricing, what you're actually paying for, and how to avoid low-quality SEO traps.
SEO vs GEO: Traditional Search vs AI-Powered Discovery
Learn the difference between SEO (traditional search) and GEO (generative engine optimization for AI) and how to build a strategy that wins on both channels.