Latest
DDR5 prices dropped 18% this quarter — time to rebuild? WordPress 6.9 ships a new default caching layer Core Web Vitals adds INP thresholds for mobile
Read more
Analytics dashboard showing revenue charts and traffic metrics on a dark background
SEO Tips

Core Web Vitals in 2026: The Technical SEO Guide

LCP, INP and CLS are simple to state and widely misunderstood. This guide covers how the numbers are actually collected, why your lab score disagrees with reality, and the diagnostic order that finds the real bottleneck in the fewest steps.

We have taken more than three hundred sites through Core Web Vitals remediation. The technical work varies enormously; the misunderstandings barely vary at all. Almost every engagement begins with the same three: a lab score treated as the truth, an average treated as representative, and a site-wide figure treated as actionable. Fix those three assumptions and the actual engineering becomes straightforward.

75thpercentile is what is assessed, not the average
28 daysrolling window before field data reflects a fix
< 600 msTTFB ceiling before LCP becomes unreachable

Field data versus lab data

There are two entirely different kinds of performance measurement, and confusing them wastes more time than any other error in this field.

Field data (RUM / CrUX)Lab data (synthetic)
SourceReal visitors on their own devices and networksOne simulated device on a simulated connection
ReflectsWhat people actually experienceWhat one configuration experiences
Used for rankingYesNo
Update latency28-day rolling windowImmediate
Good forKnowing whether you have a problemDiagnosing and verifying a fix
Bad atTelling you whyTelling you whether it matters

The workflow that follows from this is not negotiable: field data decides what to work on; lab data helps you work on it; field data confirms it worked. A team that optimises against a lab score will reliably produce a beautiful number and an unchanged experience, because the lab profile is not their audience.

The single most common mistake

Treating a lab score as the goal. Lab tools simulate one device on one throttled connection; your audience is thousands of different devices on hundreds of different networks. A lab score is a diagnostic instrument, not a target. Optimise against field data or you are optimising for a simulation.

The 28-day lag, and how to survive it

Public field datasets report a 28-day rolling window. Ship a fix today and the reported figure will not fully reflect it for four weeks; worse, it will move gradually, which invites people to declare victory or disaster on partial data.

The answer is to run your own real-user measurement alongside. A few dozen lines of JavaScript using PerformanceObserver will give you the same metrics, in your own dashboard, segmented however you like, with no 28-day lag. Every serious remediation project we run installs this in week one, because without it you are flying on a month-old instrument.

The 75th percentile rule, and why averages lie

Vitals are assessed at the 75th percentile of page loads, per metric, per device class. Three quarters of your visits must meet the threshold. The average is irrelevant, and looking at it will actively mislead you.

Here is a real distribution from a site whose average LCP was a comfortable 2.1 seconds:

PercentileLCPVerdict
50th (median)1.4 sGood
75th3.9 sNeeds improvement
90th7.2 sPoor
95th11.8 sPoor
Mean2.1 sMisleading

Half of this site's visitors had an excellent experience. A quarter of them waited nearly four seconds, and one in twenty waited almost twelve. The mean of 2.1 s described nobody. When we segmented, the slow quartile turned out to be mid-range Android devices on mobile networks arriving at one particular template — a group the team had never tested on, because everyone in the office had a fast phone on office Wi-Fi.

Segment before you conclude

Every site we have audited had at least one segment performing dramatically worse than the aggregate. Mid-range Android on cellular is the usual answer, followed by one specific template that nobody on the team ever visits. Look there first.

LCP: four sub-parts, four different fixes

Largest Contentful Paint is not one thing. It decomposes into four intervals, and each interval has entirely different remedies. Diagnosing LCP without this breakdown is guessing.

Sub-partWhat it coversHealthy shareIf it dominates
Time to First ByteRequest to first HTML byte< 40%Server, PHP/app runtime, caching, hosting
Resource load delayTTFB until the LCP resource starts downloading< 10%Discovery: preload, remove lazy-load, fix CSS-only backgrounds
Resource load timeDownloading the LCP resource< 40%Image format, dimensions, compression, CDN
Element render delayResource ready until it is painted< 10%Render-blocking CSS/JS, fonts, client-side rendering

The three causes we find most often

  1. The LCP element is lazy-loaded. A blanket loading="lazy" across all images means the browser deliberately defers the one image the metric measures. Typical cost: 800–1,500 ms. Typical fix: one attribute.
  2. The LCP image is a CSS background. The browser cannot discover it until CSS has been downloaded and parsed and the element has matched. That is a guaranteed resource-load-delay penalty. Use an <img> element.
  3. Fonts block the LCP text. When the largest element is a heading rather than an image, a late-loading webfont with font-display: block holds the paint. swap, self-hosting and preloading the one face that matters usually resolves it.
Check this today

Open your highest-traffic landing page on a real mobile device and identify the LCP element. If it has loading="lazy" on it, you have found your problem and the fix takes one minute. We find this on roughly one site in four, including sites that have already paid for a performance audit elsewhere.

Stacked bar and line charts showing web performance metrics over time
Interaction to Next Paint reports the worst interaction on the page, which is why attribution data matters more than the headline score.

INP: the metric that replaced FID

First Input Delay only measured the gap before an event handler began. That was measurable and nearly useless — it ignored how long the handler took and whether anything was ever painted. Interaction to Next Paint measures the whole thing: from the moment you tap until the browser paints the visual response, and it reports the worst interaction on the page rather than the first.

INP decomposes into three parts:

  • Input delay — the main thread was busy when you tapped.
  • Processing time — your event handlers running.
  • Presentation delay — style, layout, paint and compositing before the next frame appears.

What actually causes bad INP

In our audits, four patterns account for the large majority:

  1. Long tasks blocking input. Any task over 50 ms is a window in which a tap cannot be handled. Third-party tags and analytics initialisers are the usual authors.
  2. Doing everything synchronously in the handler. A click handler that runs 300 ms of work before yielding produces 300 ms of INP even if the visual change is trivial. Update the UI first, yield, then do the work.
  3. Large DOM trees. Past roughly 1,500 nodes, style recalculation and layout costs start to show up directly in presentation delay. Infinite-scroll pages that never remove nodes are the classic case.
  4. Hydration on interaction. Frameworks that attach behaviour lazily can run a large hydration pass on the first tap, which lands entirely inside INP.
// Update the UI first, then yield, then do the expensive part.
button.addEventListener('click', async () => {
  button.classList.add('is-loading');        // immediate visual feedback

  await new Promise(r => setTimeout(r, 0));  // let the browser paint

  await doExpensiveWork();                   // now the slow part
  button.classList.remove('is-loading');
});
The yield pattern

Paint the feedback, yield to the browser, then do the work. It does not make the work faster — it makes the interface honest about what is happening, and INP measures exactly that. This one pattern has fixed more failing INP scores for us than every bundle-size reduction combined.

Finding your worst interaction

INP reports the worst interaction, so a page can be fine ninety-nine times and fail on the hundredth. Attribution matters: record which element was interacted with, which script was executing and how long each phase took. Without attribution you will optimise the interactions that are easy to find rather than the ones that are actually failing — and in our experience the failing one is usually a filter control, a menu toggle or a “load more” button that nobody profiled.

CLS: layout shift is a discipline, not a bug

Cumulative Layout Shift scores unexpected movement of visible content. It is the easiest vital to fix and the easiest to re-break, because every new feature is an opportunity to insert something into a layout that was already stable.

CauseFixDifficulty
Images without dimensionswidth and height attributes, or aspect-ratioTrivial
Ads and embedsReserve the slot with a min-height before the ad loadsEasy
Webfont swapsize-adjust and matched fallback metricsModerate
Banners injected at the topRender server-side, or overlay rather than pushEasy
Content loaded after paintSkeleton placeholders at the final dimensionsModerate
Animating layout propertiesAnimate transform and opacity onlyEasy

One subtlety that catches teams out: shifts within 500 ms of a user interaction are excluded, because the user caused them. Shifts from your own asynchronous content are not excluded, no matter how good the reason. An accordion that opens when clicked is free; a cookie banner that appears 900 ms after load and pushes the page down is not.

Cookie banners

Almost every cookie consent implementation we audit contributes measurably to CLS, because it injects a block of content after first paint and pushes everything down. Render it server-side at a reserved height, or overlay it rather than inserting it into the flow. It is a five-minute change that often halves a CLS score.

TTFB and the metrics nobody assigns to anyone

Time to First Byte is not itself a Core Web Vital, and that is precisely why it gets neglected — it belongs to infrastructure, while LCP belongs to front-end, and neither team owns the boundary.

It is nonetheless a hard floor. If TTFB is 1.2 s, LCP cannot be under 2.5 s no matter what the front end does. We treat 600 ms as the ceiling and 200 ms as the target. Its four components:

  1. Redirects — each one costs a full round trip. A chain of three on mobile is comfortably 600 ms of nothing.
  2. Connection setup — DNS, TCP, TLS. Fixed by proximity, not by code.
  3. Server processing — application runtime, database, template rendering. Where caching pays.
  4. Response streaming — whether you flush the head early or buffer the whole document.

Two things fix most TTFB problems: full-page caching, and deleting redirect chains that accumulated over years of URL changes. Both are cheap. Neither is glamorous.

A diagnostic order that finds the cause fastest

This sequence has held up across three hundred audits. Follow it in order; each step narrows what the next one has to consider.

  1. Pull field data and segment it. By device class, by country, by page template. Never look at the site-wide figure.
  2. Find the worst segment that carries real traffic. A template with terrible vitals and forty visits a month is not your problem.
  3. Check TTFB first. If it is over 600 ms, stop and fix the server. Nothing downstream will help.
  4. Identify the LCP element on that template — on a real device, not a desktop emulation. It is frequently not what you assumed.
  5. Break LCP into its four sub-parts and attack whichever dominates.
  6. Attribute INP to a specific element and script before touching any code.
  7. Record CLS sources with the layout-shift entries, which name the offending element directly.
  8. Fix one thing. Measure. Repeat. Batched changes make attribution impossible and make regressions invisible.
One change at a time

Batching five fixes into one deployment makes it impossible to know which one worked, and impossible to know which one caused the regression that appears two weeks later. Ship one, measure, ship the next. It feels slower and it is considerably faster.

Segment by template or waste your time

Site-wide vitals are an average of averages and they hide everything useful. A publisher we worked with had an acceptable site-wide LCP and a catastrophic one on category pages — which happened to be 60% of their organic landing pages. The site-wide number said “needs improvement”; the template-level number said “your most important pages are failing”.

Segment by, at minimum: page template, device class, country or region, and connection type. Then sort by traffic × badness rather than by badness alone. The worst template on the site is often not worth fixing; the second-worst with ten times the traffic almost always is.

What vitals actually do for rankings

Let us be precise, because this is oversold in both directions.

Page experience is a real ranking input and a small one. It will not lift a weak page above a strong one. Where it matters is between pages of comparable relevance and authority — and on a competitive results page, most of the top ten are comparable. There, it is a tie-breaker, and tie-breakers decide a lot of ties.

The larger effects are indirect and, in our experience, considerably more valuable:

  • Bounce behaviour. Every additional second before content appears costs visitors, and those visitors are the ones who would have engaged.
  • Crawl efficiency. Faster responses mean more pages crawled per session, which matters enormously on large sites.
  • Conversion. The correlation between load time and conversion rate is one of the most consistently reproduced findings in the field.
  • Engineering hygiene. Sites that pass vitals tend to be sites where somebody owns the front end, and that shows up everywhere else too.
Optimise for the visitor and the ranking follows. Optimise for the score and you will get a beautiful number that nobody experiences. Priya Raghunathan, Web Performance Editor
An analytics dashboard with revenue and traffic panels
A monthly fifteen-minute review of segmented field data catches performance drift while it is still a fifteen-minute problem.

Making it stick: budgets and regression gates

Every site we have fixed and then left alone has regressed. Without a gate, performance is a project that ends; with one, it is a constraint that persists.

Three mechanisms, in order of how much work they take to set up:

  1. A written performance budget. Concrete numbers: JavaScript under 170 KB compressed, LCP image under 120 KB, no more than three third-party origins, total requests under 50. Numbers make the conversation about trade-offs instead of taste.
  2. A CI gate. Run a lab audit on every pull request against the budget. Fail the build on regression. This is the single most effective intervention we know, because it moves the cost of a regression to the moment it is introduced.
  3. A monthly field review. Fifteen minutes with the segmented data. Not to celebrate, but to catch the drift before it becomes a project.
Start with the budget

Even without CI, writing the budget down changes behaviour. When someone proposes a 90 KB carousel library, “that is more than half our JavaScript budget” is a conversation. “That feels heavy” is not.

The companion to this article is our WordPress speed playbook, which applies everything here to a real site and shows what each step was worth. If you would rather hand it over, our technical SEO audit ends with a prioritised backlog, effort estimates and a retest script — not a ninety-page PDF.

Questions readers keep asking

Because they measure different things. The lab test uses one simulated device on one throttled connection with a cold cache and no browser extensions. Your field data aggregates thousands of real sessions on real hardware with warm caches, extensions, and network conditions the simulation does not model. A perfect lab score with failing field data usually means your real audience has slower devices or slower networks than the simulation assumes — which is extremely common outside Western Europe and North America.

You will see the first movement within a few days and the full effect after twenty-eight, because the public dataset is a 28-day rolling window. This is why we install real-user measurement on day one of any engagement — your own RUM shows the change within hours and lets you confirm a fix before the public data catches up.

For ranking, no. For everything else, yes. Checkout flows, application dashboards and account pages are usually excluded from search entirely, and they are exactly where slow interactions cost you money rather than position. We regularly find that the worst INP on a site is on a page that has never received a single visit from search.

Rarely. The distance from failing to passing is where essentially all the user benefit and all the ranking benefit sit. The distance from passing to perfect usually costs several times as much engineering effort for a difference no visitor can perceive. Pass comfortably, put a regression gate in place, and spend the remaining time on content.

Yes, but the defaults work against you. Client-side rendering delays LCP because content cannot paint until JavaScript has downloaded, parsed and executed, and hydration lands squarely in INP. The sites we see passing use server-side rendering or static generation for the initial view, hydrate selectively rather than wholesale, and measure soft navigations separately — because a route change that feels instant to a developer on a fast machine often is not.

Priya Raghunathan
Web Performance Editor

Priya Raghunathan

Priya audits WordPress and headless sites for a living. She has taken more than three hundred sites through Core Web Vitals remediation and still keeps a folder of the worst plugin code she has ever seen.

Keep reading

Related guides