Core Web Vitals in Practice: Measuring and Fixing LCP, INP and CLS
October 14, 2026 · Devhuset Team
Every fast website feels the same: pages appear quickly, taps respond immediately, and nothing jumps around while you read. Slow sites feel broken even when every feature works. Core Web Vitals give that gut feeling a number, so a team can measure it, argue about it less, and improve it on purpose.
What Core Web Vitals Actually Measure
There are three metrics, and each one answers a different question a real visitor is asking.
Largest Contentful Paint (LCP) measures how long the biggest element in the viewport takes to appear, usually a hero image, a heading, or a video poster. A good LCP is 2.5 seconds or less. Between 2.5 and 4 seconds it needs work, and beyond 4 seconds it is a problem.
Interaction to Next Paint (INP) measures responsiveness: when someone taps, clicks, or types, how long until the page visibly reacts. A good INP is 200 milliseconds or less, up to 500 milliseconds needs work, and anything above that feels sluggish. INP replaced the older First Input Delay metric in March 2024 because it reflects the worst interaction rather than only the first one.
Cumulative Layout Shift (CLS) measures unexpected movement. It scores how much visible content shifts and how far, summed across the page load. A good score is 0.1 or below, 0.1 to 0.25 needs work, and above 0.25 is poor.
One detail matters more than the thresholds: each metric is judged at the 75th percentile of real page loads. A green score does not mean every visit is fast. It means three out of four are.
Field Data Beats Lab Data
There are two ways to measure these numbers, and they answer different questions.
Lab tools such as Lighthouse and WebPageTest run a single page load on a simulated device and connection. That makes them repeatable and useful for catching a regression before it ships, but a lab run is one controlled visit. It cannot tell you how your visitors on real phones and real networks are doing.
Field data comes from real sessions. The Chrome UX Report aggregates anonymised data from people who have opted in, and PageSpeed Insights shows that field data alongside a lab run. Search Console groups the same data by URL so you can see which sections of a site are struggling. For your own dashboards, the open-source web-vitals library reports the same metrics from your live traffic.
The practical rule: use lab data to reproduce and debug, and field data to decide what is worth fixing.
Improving LCP
LCP is usually a loading problem, and it breaks down into four levers.
Time to first byte sets the ceiling. If the server, the database, or the CDN in front of them is slow, nothing downstream can make up the difference. Caching, a CDN close to your users, and trimming slow queries or upstream calls all lower that floor.
Render-blocking resources come next. A stylesheet in the head or a synchronous script stops the browser from painting until it arrives. Deferring non-critical JavaScript and inlining only the CSS needed above the fold lets the page paint sooner.
Images are the most common culprit, because the largest element is often a picture. Serve modern formats such as WebP or AVIF, size them to the slot they fill with a responsive srcset, and preload the hero image so it is discovered early. Lazy-loading is valuable for images below the fold, but applying it to the LCP image delays exactly the thing you are trying to speed up.
Fonts are the last lever. A custom font that blocks text rendering shows nothing until it loads. Font-display swap and preloading the font file let text appear immediately in a fallback face while the real one downloads.
Improving INP
INP is about the main thread. Every interaction competes with JavaScript that is already running, so a busy thread makes the whole page feel unresponsive.
Long tasks are the enemy. When a single chunk of JavaScript runs for hundreds of milliseconds, clicks and keystrokes have to wait. Breaking large tasks into smaller pieces, and yielding to the browser between them with setTimeout, requestIdleCallback, or scheduler.yield, lets input be handled promptly.
Third-party scripts deserve suspicion. Analytics, chat widgets, and testing tools all add JavaScript you do not control, and they often run during the most sensitive moments. Loading them lazily, after the page is interactive, keeps them out of the critical path.
Hydration is another common source of delay on modern frameworks. If a server-rendered page still has to attach event handlers to everything before it responds, the first interactions feel frozen. Approaches such as islands, partial hydration, and streaming HTML let the parts of the page that are already visible become interactive sooner.
Audit the handlers themselves too. An input that triggers an expensive recalculation on every keystroke is a common pattern, and debouncing it is often enough to bring INP back into range.
Reducing CLS
Layout shift is almost always a sizing problem, and it is the easiest of the three to fix once you can see it.
Give every image, video, iframe, and embed explicit dimensions, or set an aspect ratio in CSS. When the browser knows how much space an element needs, it reserves that space before the asset arrives. Ad slots and dynamically inserted banners are the classic offenders, so reserve a fixed minimum height and nothing below them gets pushed down.
Avoid injecting content above what a reader is already looking at. A cookie notice that shoves the article down the page, or a notification bar that appears a second after load, registers as a shift. Anchor those elements with fixed or sticky positioning instead.
Animate with transform and opacity rather than properties such as top or width, which force the layout to recalculate. And when you use custom fonts, choose a fallback with similar metrics, or use size-adjust, so text does not reflow when the real font swaps in.
How to Run a Core Web Vitals Test
A repeatable Core Web Vitals test follows the same loop whether you are checking one page or a whole site.
Start with field data for the template you care about, not the homepage. Sort pages by the 75th percentile and work on the worst offender first, because a slow checkout hurts more than a fast blog index helps.
Reproduce the problem in the lab. Open the specific URL in PageSpeed Insights or a throttled WebPageTest run, and watch the filmstrip to see which element is late, which task is long, or what moves.
Fix one thing at a time and re-measure. Performance work is easy to fool yourself about, and changing five things at once tells you nothing about which one helped.
Then confirm the change in field data, which takes days to catch up because it reflects real traffic. A lab score that improves while the field number stays flat usually means you fixed something your visitors were not experiencing.
Keeping Scores From Slipping
A single good measurement is a snapshot. Keeping the numbers healthy means treating performance as a feature with a budget.
Set thresholds that fail a build, such as a maximum LCP or a cap on JavaScript shipped, and enforce them in continuous integration with Lighthouse CI. Alert on field data so you hear about a regression from real users instead of discovering it in a review months later. Make the numbers visible to the people who can act on them, because a metric nobody owns drifts.
The three values only matter insofar as they describe something a person feels. Fast, responsive, stable pages keep readers around, and Core Web Vitals simply make that experience something a team can plan for.