Skip to content
Black HartConsulting
PerformanceMarch 16, 20268 min read

The Core Web Vitals playbook

LCP, CLS, INP. Three numbers Google uses to rank you. Here’s the actual order of operations we use to get them into the green — in about a week, for most sites.

By Suhaib Chaudhry

Core Web Vitals playbook — a developer working on a laptop with performance metrics on screen

Core Web Vitals is how Google measures whether your site feels fast. There are three numbers: Largest Contentful Paint (LCP), Cumulative Layout Shift (CLS), and Interaction to Next Paint (INP). You want them green. This is the order we fix them in.

Step 1: Measure from real users, not Lighthouse

Lighthouse runs in a controlled lab on your machine. Real users are on flaky 4G, on a phone from 2019. Pull Core Web Vitals from Google’s Chrome UX Report (CrUX) or from your analytics platform. That’s what Google is actually ranking on.

Step 2: Attack LCP first

LCP is almost always the highest-impact metric. It’s the time until the largest visible element paints — usually the hero image or the hero headline.

  • Preload the hero image. One line in your <head>.
  • Serve hero images as AVIF or WebP, never JPEG, with a responsive <picture> or srcset.
  • Set width and height on every image so the browser can allocate space before it loads.
  • Self-host your fonts with font-display: swap. Never use Google’s CDN directly.

These four changes alone take a median site from 3.5s LCP to under 1.5s.

Step 3: Kill layout shift

CLS is cheap to fix. Every layout shift is a thing that rendered before its space was reserved. Two culprits cover 90% of cases:

  • Images and videos without explicit dimensions
  • Late-loading ads or embeds (YouTube, Twitter) without a fixed-height placeholder

Wrap embeds in a container with a fixed aspect ratio. Always declare image dimensions. CLS goes green.

Step 4: INP is where you earn your money

INP replaced FID in 2024 and it’s harder to fix. It’s the worst-case interaction latency on the page — click, type, scroll. It goes bad because the main thread is busy running a huge bundle of JavaScript.

  • Audit your bundle. Remove anything over 50kb that you’re not using.
  • Lazy-load anything below the fold.
  • Debounce scroll and resize listeners. Never run expensive logic on every frame.
  • Break up long tasks with requestIdleCallback or scheduler.yield.

Step 5: Ship and re-measure

CrUX updates on a 28-day rolling window. You won’t see the green bar until a full month after your deploy. Don’t panic, don’t re-optimize prematurely. Ship, wait 28 days, re-measure.

A fast site isn’t a lucky site. It’s a site where someone with authority said "we’re going to take a week and fix this" and then actually took the week.

Tags

  • Core Web Vitals
  • Performance
  • Optimization