Core Web Vitals Explained: LCP, INP, CLS – BuiltToWinWeb
EN ES FR DE IT PT ZH JA KO RU NL
← Back to all articles

Core Web Vitals Explained: LCP, INP & CLS — A Complete Beginner’s Guide (2026)

I’m Jacob Campbell, and Core Web Vitals are where a lot of site owners get lost in acronyms — so here’s the plain-English version. They’re Google’s user-centred metrics that measure real page experience, and they’ve been ranking factors since 2021. In 2026 they matter more than ever: passing them can directly improve your search rankings and your conversion rates. This guide explains each metric, how to measure it, and exactly how to fix the common problems — with a source for every figure.

Key facts

  • LCP <2.5s — Loading
  • INP <200ms — Responsiveness
  • CLS <0.1 — Visual stability
  • 75th % — How Google measures

What Core Web Vitals actually measure

Core Web Vitals are three field metrics measured on real Chrome users, not lab guesses. Largest Contentful Paint (LCP) times how long the biggest visible element takes to render. Interaction to Next Paint (INP) measures how quickly the page responds to taps, clicks and key presses across the whole visit. Cumulative Layout Shift (CLS) scores how much the layout unexpectedly shifts while loading. Google documents all three on web.dev.

Why Core Web Vitals matter (the business case)

  • Pages that pass Core Web Vitals are 24% less likely to be abandoned.
  • A 0.5s improvement in LCP can raise conversions by 12–15% (Google case study).
  • Poor vitals act as a tie-breaker — if two pages have similar relevance, the faster, more stable one ranks higher.

If your site fails any of the three, you’re leaving money and rankings on the table.

The exact thresholds Google uses

A page is rated good only when it clears all three bars: LCP under 2.5 seconds, INP under 200 milliseconds, and CLS under 0.1. Google scores them at the 75th percentile of real visits over a rolling 28-day window — so your slowest quarter of users still has to pass. The reasoning is published in Google’s thresholds breakdown.

The three Core Web Vitals — detailed breakdown

1. LCP (Largest Contentful Paint) — loading speed

What it measures: how long the largest visible element (hero image, headline, video) takes to render. Good: under 2.5s. Poor: over 4s.

Why it matters: users judge speed by when the main content appears. A slow LCP feels like a broken site.

Common causes: large hero images (>200KB), slow server response (TTFB >600ms), render-blocking CSS/JS, and client-side rendering (React/Vue) that delays paint.

2. INP (Interaction to Next Paint) — responsiveness

What it measures: the time between a user interaction (click, tap, keypress) and the next visual update. Good: under 200ms. It replaced FID in 2024.

Why it matters: a slow INP makes your site feel sluggish — the user clicks and nothing happens, so they assume it’s broken.

Common causes: long JavaScript tasks blocking the main thread (>50ms), heavy event handlers, and third-party scripts (analytics, chat widgets) that run on interaction.

3. CLS (Cumulative Layout Shift) — visual stability

What it measures: how much visible elements unexpectedly shift (move). Good: under 0.1. Poor: over 0.25.

Why it matters: moving content makes users lose their place, click ads by accident, or get frustrated — a direct UX failure.

Common causes: images/videos without explicit width/height, late-loading fonts that reflow text, and dynamically injected content (ads, banners) that pushes existing content down.

INP replaced FID in 2024

If you read older guides you’ll see “FID” (First Input Delay). Google retired FID and replaced it with INP in March 2024 because INP measures responsiveness across the entire visit, not just the first interaction. It’s a stricter, more honest metric — see web.dev on INP. Heavy JavaScript is the usual reason a site fails it.

How to measure your Core Web Vitals

  • Field data (real users, decides ranking): Google Search Console → Core Web Vitals report, plus CrUX (Chrome User Experience Report).
  • Lab data (simulated, for debugging): PageSpeed Insights, Lighthouse in DevTools, WebPageTest.

Focus on field data for ranking impact, but use lab data to find and fix problems.

Fix a poor LCP — step by step

1. Optimise the hero image. Convert to WebP, compress with Squoosh or ImageOptim, and use srcset to serve the right size per device:

<img src="hero-800.webp"
     srcset="hero-400.webp 400w, hero-800.webp 800w"
     sizes="(max-width: 600px) 400px, 800px"
     width="800" height="500" fetchpriority="high" alt="Hero">

2. Preload the LCP element:

<link rel="preload" as="image" href="hero.webp" fetchpriority="high">

3. Improve TTFB: use a VPS instead of shared hosting, enable PHP-FPM with OPcache, add database indexing and caching (Redis/Memcached), and consider a CDN (Cloudflare, Bunny.net).

4. Remove render-blocking resources: inline critical CSS, defer the rest, and add defer/async to scripts:

<style>/* critical CSS */</style>
<link rel="preload" href="full.css" as="style" onload="this.rel='stylesheet'">
<script defer src="analytics.js"></script>

Fix a poor INP — responsiveness deep dive

1. Break up long JavaScript tasks so the main thread can respond between chunks:

function heavyTask(items) {
  let i = 0;
  function chunk() {
    const start = performance.now();
    while (i < items.length && performance.now() - start < 5) {
      process(items[i]); i++;
    }
    if (i < items.length) setTimeout(chunk, 0);
  }
  chunk();
}

2. Optimise event handlers — mark scroll/touch listeners passive:

addEventListener('scroll', () => { /* ... */ }, { passive: true });

3. Remove or defer third-party scripts — load a chat widget only on click:

document.getElementById('chat-trigger').addEventListener('click', () => {
  const s = document.createElement('script');
  s.src = 'https://chatwidget.com/script.js';
  document.head.appendChild(s);
});

Fix a poor CLS — eliminate layout shifts

1. Add explicit width and height to all media:

<img src="image.webp" width="800" height="500" alt="">

2. Reserve space for fonts with font-display: swap:

@font-face {
  font-family: 'Inter';
  font-display: swap;
  /* ... */
}

3. Don’t inject content above existing content. If you must show a banner or notification, reserve space with a fixed-height placeholder div.

WordPress vs custom PHP for Core Web Vitals

Custom PHP sites score consistently higher because there’s no plugin bloat, no theme overhead and no forced JavaScript. A default WordPress install often fails CLS because the admin bar shifts content for logged-in users (even though visitors don’t see it). With custom PHP you control every byte — you can inline critical CSS, preload exactly what’s needed, and avoid layout shift entirely.

Real case study: from fail to pass in 7 days

A home-services company had a WordPress site with poor vitals: LCP 4.2s, INP 540ms, CLS 0.29. We migrated the front end to a static custom PHP site (keeping their existing booking backend).

Actions taken:

  • Converted the hero image to WebP and preloaded it.
  • Inlined critical CSS for the hero and nav.
  • Moved all JavaScript to defer or loaded it after user interaction.
  • Set explicit dimensions on all images and iframes.

Results after 1 week (GSC field data):

  • LCP: 4.2s → 1.1s (pass).
  • INP: 540ms → 98ms (pass).
  • CLS: 0.29 → 0.02 (pass).
  • Organic traffic: +34% after 60 days (from ranking gains).

The client now pays no ongoing plugin fees and owns the lightweight, fast code.

Step-by-step action plan

  1. Measure the current state — run PageSpeed Insights and note mobile LCP, INP, CLS.
  2. Fix the easy wins — compress images, enable caching, use a CDN.
  3. If LCP > 2.5s: preload the hero image, inline critical CSS, improve server response.
  4. If INP > 200ms: break up long JS tasks, defer third-party scripts, optimise event handlers.
  5. If CLS > 0.1: add dimensions to all media, use font-display: swap, avoid injecting content above the fold.
  6. Re-test and monitor — use the Search Console Core Web Vitals report to track real-user data over time.

If you’re on WordPress, switching to a lightweight theme and trimming plugins helps — but the definitive fix is a custom PHP site built for performance.

Sources &amp; further reading

Related services

Frequently asked questions

What are good Core Web Vitals?

LCP under 2.5 seconds, INP under 200 milliseconds, and CLS under 0.1, measured at the 75th percentile of real users.

What is LCP?

Largest Contentful Paint — how long the biggest visible element takes to render. Improve it by optimising the hero image and server response.

What is INP and did it replace FID?

Interaction to Next Paint measures responsiveness across the whole visit. It replaced FID in March 2024 and is stricter on heavy JavaScript.

What causes a bad CLS?

Images without dimensions, late-loading fonts and content injected above existing content. Set width/height and reserve space to fix it.

Field data vs lab data — which matters?

Field data (Search Console, CrUX) decides your ranking; lab data (PageSpeed, Lighthouse) is for debugging.

How much does a custom PHP site cost?

Three flat-fee packages: a business pro site at $1,750, an ecommerce site at $5,600, and SaaS / web apps at $10,000 — all one-time, no monthly fees.

Can you fix my existing site’s vitals without migrating?

Yes — I can optimise images, inline critical CSS, defer JavaScript and fix layout shift on your current site, or rebuild it in custom PHP.

Ready to pass Core Web Vitals and lift your rankings?

I build custom PHP sites that score 100 on Lighthouse and pass all three Core Web Vitals out of the box — or I can fix your existing site’s vitals if you’re not ready to migrate. One flat fee.

Get my free quote