How to Improve Core Web Vitals: A Technical Playbook

How to Improve Core Web Vitals: A Technical Playbook | Swarm Digital

Improving Core Web Vitals means fixing the root cause behind each of the three metrics, Largest Contentful Paint (LCP), Interaction to Next Paint (INP), and Cumulative Layout Shift (CLS), rather than installing a plugin and hoping the needle moves. You need to separate field data (what real users experience) from lab data (what a single test run shows), diagnose which specific resource or render-blocking pattern is causing the failure, and fix it at the code or infrastructure level. This guide walks through that diagnostic process for any stack, including JavaScript-heavy frameworks and headless CMS setups where generic "install this plugin" advice simply doesn't apply.

Why most Core Web Vitals advice doesn't work

Search "how to improve Core Web Vitals" and you'll mostly get WordPress hosting posts: install a caching plugin, enable lazy loading, pick a "fast" theme. That advice isn't wrong, it's just incomplete, and it's useless if you're running Next.js, a headless Shopify frontend, or a custom React app with no plugin ecosystem at all.

Core Web Vitals are rendering and interaction metrics. They're caused by specific technical decisions: what blocks the main thread, what the browser has to download before it can paint, what shifts after the fact. Fixing them requires reading Chrome's performance data correctly and tracing each failure back to the line of code, the font file, or the third-party script responsible. That's the job of technical SEO services, and it's the same diagnostic process regardless of what your site is built on.

Step 1: Separate field data from lab data

Before touching anything, know which data source you're looking at, because they measure different things and often disagree.

  • Field data (CrUX, Search Console): Real Chrome users, aggregated over 28 days. This is what Google uses for ranking signals and what shows up in the Core Web Vitals report in Search Console. It reflects real devices, real networks, real third-party script load.
  • Lab data (Lighthouse, PageSpeed Insights, WebPageTest): A single simulated run on a fixed device and connection profile. Useful for debugging a specific page, but it can look great while your field data is failing, especially if your real users are on mid-range phones or slow connections your lab test doesn't simulate.

If Search Console shows a metric failing but Lighthouse shows it passing, trust the field data and dig into why the gap exists. Often it's a third-party script, a specific device class, or a page template the lab test didn't sample. The Chrome User Experience Report is the authoritative source for field data if you want to query it directly.

Step 2: Diagnose and fix LCP

LCP measures when the largest visible element (usually a hero image, a headline, or a background image) finishes rendering. Google's threshold for "good" is 2.5 seconds or less.

Find the LCP element first

Open Chrome DevTools Performance panel or PageSpeed Insights and identify which element is actually being measured. It's often not what you'd guess, sometimes it's a background CSS image, not the hero <img> you optimized.

Common causes and fixes

  • Slow server response (TTFB): If your Time to First Byte is over 600ms, no amount of frontend tuning will save your LCP. Check your hosting, your database query times, and whether you're serving from a CDN edge node close to your users.
  • Render-blocking resources: CSS and synchronous JavaScript in the <head> delay paint. Inline critical CSS, defer non-critical stylesheets, and move scripts to async or defer.
  • Unoptimized LCP image: Serve modern formats (WebP or AVIF), set explicit width/height, and add fetchpriority="high" to the LCP image tag so the browser prioritizes it over other requests.
  • Client-side rendering delay: On JS-heavy frameworks, if the LCP element only appears after hydration, you're paying a JavaScript execution tax before anything paints. Server-side render or statically generate the above-the-fold content where possible, even if the rest of the page hydrates client-side.
  • Late-discovered resources: If the LCP image is loaded via a JavaScript framework's lazy image component, the browser can't discover it early. Use a <link rel="preload"> for the LCP resource, or avoid lazy-loading anything above the fold.

Step 3: Diagnose and fix INP

INP replaced First Input Delay as the responsiveness metric in March 2024, and it measures the full latency of a user interaction: input delay, processing time, and the time to the next paint. Google's threshold for "good" is 200 milliseconds or less.

What actually causes bad INP

INP failures almost always trace back to long tasks, JavaScript execution that blocks the main thread for more than 50ms, preventing the browser from responding to user input.

  • Break up long tasks: Use scheduler.yield() or setTimeout chunking to split large JavaScript operations so the main thread can breathe between chunks and respond to input.
  • Audit third-party scripts: Tag managers, chat widgets, and analytics scripts are frequent INP killers. Load them with async or defer, and consider whether each one justifies its performance cost.
  • Reduce JavaScript bundle size: Code-split by route so users aren't downloading and parsing JavaScript for parts of the app they haven't visited. This matters enormously on single-page applications where the entire app ships on first load.
  • Debounce expensive event handlers: Input handlers, scroll listeners, and resize handlers that trigger re-renders or layout recalculation on every event are common culprits. Debounce or throttle them.
  • Watch for hydration mismatches on headless/JS frameworks: If a framework re-hydrates large portions of the DOM on interaction, that re-hydration cost counts against INP. Profile interaction traces in DevTools to find exactly which component is re-rendering.

If you're managing this across a framework your team didn't build in-house, or across a headless CMS where the frontend and content layer are decoupled, this is where a technical SEO consultant earns their fee: tracing a 300ms interaction delay back to a specific component usually takes someone who can read a performance trace, not just run an audit tool.

Step 4: Diagnose and fix CLS

CLS measures unexpected layout movement during the page's lifecycle. Google's threshold for "good" is 0.1 or less.

Where layout shift actually comes from

  • Images and embeds without dimensions: Any element that loads asynchronously and doesn't reserve space will push content around when it arrives. Always set explicit width and height attributes, or use the aspect-ratio CSS property.
  • Web fonts causing FOIT/FOUT: If your custom font loads after a fallback font has already rendered, text reflows. Use font-display: optional or swap carefully, and preload critical font files.
  • Dynamically injected content: Cookie banners, promotional bars, and ads that inject above existing content without reserving space are a top CLS cause. Reserve the space in the layout before the content loads, don't let it push everything down after the fact.
  • Animations that use layout-triggering properties: Animating width, height, top, or left triggers layout recalculation. Use transform and opacity instead, which the browser can composite without reflowing the page.

Step 5: Build a monitoring loop, not a one-time fix

Core Web Vitals aren't a project you finish, they shift every time you ship a new feature, swap a third-party vendor, or add a marketing script. Set up:

  1. Real User Monitoring (RUM) to track field performance continuously, not just at audit time.
  2. A performance budget enforced in CI, so a pull request that pushes LCP past threshold fails the build before it ships.
  3. Quarterly manual audits cross-referencing Search Console's Core Web Vitals report against your own RUM data to catch template-specific or device-specific regressions.

When to bring in outside technical help

If your team can read a Lighthouse report but struggles to trace a long task back to the component causing it, or if your CLS keeps regressing every time marketing adds a new script, that's a sign the diagnostic work needs someone who does this full-time. For a sense of what a proper engagement actually covers, see our breakdown of what's included in technical SEO services and how to choose the right technical SEO agency for your stack.

If you're ready to get a straight diagnosis of what's actually causing your Core Web Vitals failures and a fix plan your dev team can implement, contact our technical SEO team for an audit.

Matthew Weitzman, Swarm Digital
Written by Matthew Weitzman Managing Partner, Head of Tech & SEO

Matthew Weitzman co-founded Swarm Digital to build the agency he wished existed, technical enough to actually fix what's broken, and honest enough to tell you the truth about it. He leads the engineering and SEO side of the business, from web-application architecture to the technical SEO that decides whether Google can even read a site. His approach is code-first: he'd rather solve a ranking problem at the source than paper over it with a plugin. He writes about SEO, web development, Core Web Vitals, and where AI is taking search.

See more articles by Matthew →

Related reading

← All posts