Related: PostgreSQL vs MongoDB: How to Actually Choose in 2026
Core Web Vitals are three numbers Google uses to judge how a page feels to a real person. They are a small ranking signal. More importantly, they track things that genuinely cost you money: slow pages lose visitors, and pages that jump around lose clicks.
In March 2024 Google replaced First Input Delay with Interaction to Next Paint. INP is a much stricter test, and many sites that passed the old set now fail. This guide covers what each metric measures, what counts as a pass, and the fixes that actually move the numbers.
The three metrics
LCP: Largest Contentful Paint
How long until the biggest thing on screen has loaded. Usually the hero image or the main heading.
- Good: under 2.5 seconds
- Needs work: 2.5 to 4 seconds
- Poor: over 4 seconds
INP: Interaction to Next Paint
How long the page takes to visibly respond after a click, a tap, or a key press. It looks at nearly every interaction during the visit and reports close to the worst one.
- Good: under 200 milliseconds
- Needs work: 200 to 500 milliseconds
- Poor: over 500 milliseconds
This is the one that catches people out. The old metric only measured the delay before your code started running. INP measures the whole thing: the delay, your handler, and the browser painting the result.
CLS: Cumulative Layout Shift
How much the page jumps around while loading. A score, not a time.
- Good: under 0.1
- Needs work: 0.1 to 0.25
- Poor: over 0.25
Field data is what counts
This trips up a lot of teams. There are two kinds of measurement:
- Lab data. Lighthouse, PageSpeed Insights' simulated run, WebPageTest. One synthetic load on a machine you chose. Useful for debugging.
- Field data. Real visits from real people on real devices and real networks. Google collects this in the Chrome User Experience Report.
Google uses field data. A perfect Lighthouse score means nothing if your actual visitors are on mid range Android phones and slow connections.
Two more things about field data:
- It is measured at the 75th percentile. Three quarters of visits must pass, not the average.
- It runs on a 28 day rolling window. A fix you ship today will not show in Search Console for weeks. Do not panic and revert.
Check field data in Search Console under Core Web Vitals, or in PageSpeed Insights where the top panel is field data and the bottom panel is lab.
Fixing LCP
Work through these in order. The first two fix most cases.
- Measure time to first byte. If your server takes 800ms to respond, you have already spent a third of your budget before anything renders. Cache rendered pages, add an index to the slow query, or move to a faster host.
- Find the LCP element. PageSpeed Insights names it. Usually a hero image.
- Do not lazy load it. A hero image with
loading="lazy"is a common and expensive mistake. Usefetchpriority="high"instead. - Serve it in the right size and format. AVIF or WebP, sized for the slot it fills. A 3000px image in a 600px box wastes most of the download.
- Preload it if it is discovered late, for example inside a carousel or set by CSS.
- Stop render blocking resources. Inline the small amount of CSS needed for the top of the page. Defer the rest. Never block rendering on a font.
Fixing INP
INP is a main thread problem. The browser cannot paint while JavaScript is running.
- Find the slow interactions. Use the Performance panel in Chrome DevTools, or the web-vitals library to log real INP values with the element that caused them.
- Break up long tasks. Anything over 50ms blocks the page. Split loops and yield back to the browser between chunks.
- Show feedback before doing the work. Paint the pressed state or the spinner first, then run the expensive logic. The visible response is what INP measures.
- Cut the JavaScript you ship. Less code parsed, compiled and run means fewer long tasks. Audit your bundle and remove what you do not use.
- Watch third party scripts. Chat widgets, tag managers, analytics, A/B testing tools and ad scripts all run on the same thread as your code. They are a frequent cause.
- Avoid layout thrash. Reading a layout property then writing to the DOM in a loop forces the browser to recalculate repeatedly. Batch the reads, then batch the writes.
Fixing CLS
CLS is almost always something that appears late and pushes existing content down.
- Put width and height on every image and video. The browser then reserves the space before the file arrives. If you style by aspect ratio, add
height: auto, or the attributes will override the ratio. - Reserve space for ads and embeds. Give the container a fixed minimum height even when empty.
- Load fonts without a swap jump. Use
font-display: swapwith a fallback that has similar metrics, orsize-adjustto match them. - Never insert content above what someone is reading. Cookie bars, promo banners and notification strips belong in an overlay or at the bottom, not pushed into the top of the flow.
- Animate transform and opacity only. Animating width, height, top or margin causes layout work and shifts.
A realistic order of work
If you have limited time, this order gives the most improvement per hour:
- Add width and height to every image. Cheap, fast, fixes most CLS.
- Fix the hero image: correct format, correct size, high priority, not lazy.
- Get time to first byte under 400ms with caching.
- Remove or defer the third party scripts you cannot justify.
- Only then start splitting long tasks.
What not to worry about
- A perfect 100 score. Passing the three thresholds is the goal. The composite score is a debugging aid, not a target.
- Small differences. 2.3s and 2.4s LCP are the same outcome.
- Lab results that disagree with the field. The field is right. Your test machine is probably faster than your visitors' phones.
- Chasing it forever. Core Web Vitals is one signal among many. Content and relevance still matter far more.
If your numbers are red and you are not sure why, send us the URL. Performance work is a regular part of what we do on web builds.
Comments