Google measures three things: Largest Contentful Paint, Interaction to Next Paint and Cumulative Layout Shift. It measures them from real Chrome users, at the 75th percentile, over a trailing 28-day window, split between mobile and desktop. Everything else you see in a performance tool — the big coloured score out of 100, Total Blocking Time, Speed Index, Time to First Byte — is diagnostic. Google does not use it to assess your pages.
That gap is where most WordPress site owners waste money. They chase a Lighthouse number that includes metrics Google ignores and excludes a metric Google actually measures. Below is what is in scope for 2026, what is not, and the specific places the two diverge.
What are the Core Web Vitals in 2026?
Three metrics, unchanged in composition since Interaction to Next Paint replaced First Input Delay as a stable Core Web Vital in 2024. Google has committed to a predictable annual cadence with prior notice for changes, so the set is stable going into 2026.
| Metric | What it measures | Good | Needs improvement | Poor |
|---|---|---|---|---|
| LCP — Largest Contentful Paint | When the biggest visible element finishes rendering | ≤ 2.5 s | 2.5 – 4.0 s | > 4.0 s |
| INP — Interaction to Next Paint | Delay between a tap/click/keypress and the next painted frame | ≤ 200 ms | 200 – 500 ms | > 500 ms |
| CLS — Cumulative Layout Shift | Largest burst of unexpected layout movement | ≤ 0.1 | 0.1 – 0.25 | > 0.25 |
A page passes only if all three are in the “good” band at the 75th percentile. One metric in the amber band means the page does not pass, no matter how good the other two are.
Why the 75th percentile matters more than the average
Your analytics probably shows a mean load time. Google does not use the mean. It takes the value below which 75% of real page views fall, so the slowest quarter of your visitors sets your result.
If three-quarters of your traffic is on fast desktop connections and a quarter is on mid-range Android phones over mobile data, the Android quarter is what gets measured. This is the most common reason a site owner says “but it’s fast on my machine” while the field data disagrees.
What Google ignores
The Lighthouse performance score
The number in the circle at the top of PageSpeed Insights is a lab simulation. It is not a ranking input, and it is not weighted the way the Core Web Vitals are. Here is the published Lighthouse weighting against what Google actually assesses:
| Metric | Weight in Lighthouse score | A Core Web Vital? |
|---|---|---|
| Total Blocking Time | 30% | No |
| Largest Contentful Paint | 25% | Yes |
| Cumulative Layout Shift | 25% | Yes |
| First Contentful Paint | 10% | No |
| Speed Index | 10% | No |
| Interaction to Next Paint | 0% | Yes |
Read the last row again. INP — one of the three metrics Google assesses — contributes nothing to the Lighthouse score. Total Blocking Time, which Google does not assess, is the heaviest single component at 30%. TBT is a lab proxy for responsiveness, and it is a reasonable one, but it is measured on a synthetic page load with no real user interaction. It can look fine while your actual INP is poor, and the reverse.
This is why a 95 score and a failing Core Web Vitals report are not a contradiction. They are two different measurements of two different things. We wrote about that divergence in more depth in why your WordPress site takes 8 seconds to load.
Scrolling, hovering and zooming
INP counts exactly three interaction types: clicking with a mouse, tapping a touchscreen, and pressing a key. Scroll performance, hover states and pinch-zoom are excluded entirely.
A site that janks on scroll because of a parallax header has a real user experience problem that will never appear in INP. It can still hurt you indirectly: the effect occupies the main thread, so a tap landing during the jank waits longer for its callback to run.
Time to First Byte
TTFB is not a Core Web Vital. Google publishes thresholds for it — 0.8 seconds or less is good, over 1.8 seconds is poor — and documents it as a diagnostic that precedes FCP and LCP, not as a metric you must pass.
It still matters, because LCP cannot start until the first byte arrives — a 1.2-second TTFB eats half your 2.5-second LCP budget before a pixel renders. But it is a means to an LCP end, not a target in its own right. A site with a 0.4-second TTFB and a 5-second LCP has a rendering problem, not a server problem.
The distinction worth drawing is between cached and uncached TTFB. A static page served from cache looks fine on almost any host. Cart, checkout, wp-admin and every logged-in view bypass the cache entirely, and that is where shared hosting shows its real latency. If those pages are consistently slow while your cached pages are fast, you are at a hardware ceiling and no plugin will move it — which is the specific problem our own WordPress hosting, WPHoster, is built around.
Pages Google has no data for
The Chrome User Experience Report only includes a URL if it meets two criteria: it is publicly discoverable (returns 200, no noindex header or meta tag), and it has enough traffic for a statistically meaningful sample. Google does not publish the traffic threshold.
When a specific URL falls below it, PageSpeed Insights falls back to origin-level data — the aggregate of every page on the site. When the origin also falls below the threshold, you get no field data at all, just the lab simulation.
For most small-business WordPress sites, individual blog posts and service pages have no URL-level data and are judged on the origin aggregate — so one bloated template drags down how every page is assessed. It also means a fix deployed today only becomes fully visible in the field data roughly a month later, as the 28-day window rolls forward.
What changed going into 2026
Soft navigations are now measurable
Single-page-app style navigations — where JavaScript swaps the page content without a full page load — have historically been invisible to Core Web Vitals. The metrics were tied to hard navigations, so a user clicking through five views of a React or Vue front-end generated one set of measurements for the first view and nothing after.
Chrome’s soft navigations feature is enabled by default from Chrome 151, and in Edge 151. Firefox and Safari do not support it. Google’s own documentation is explicit that how soft navigations will be reported in CrUX has not been decided yet.
For a standard WordPress site this changes nothing — classic multi-page WordPress produces hard navigations. It matters if you are running a headless front-end, a WooCommerce store with an AJAX-driven filtered catalogue, or a theme that intercepts internal links for page transitions. In those cases, views that have never been measured are about to become measurable, and what you see in CrUX may get worse without anything on the site getting slower.
What has not changed: Google assesses real Chrome users, not your test runs. Any tool that gives you a number without pulling CrUX is giving you a simulation. If you are unsure whether your field data has enough volume to be reliable, or whether a fix has actually landed in the 28-day window, ask us to check your CrUX data before you spend anything on optimisation — there is no point buying a fix for a problem the field data does not show.
How the three metrics actually break down
LCP: four phases, and only one of them is the image
LCP is the render time of the largest contentful element — an <img>, an <image> inside an SVG, a <video> poster frame, an element with a CSS url() background, or a block-level element containing text. Chrome applies heuristics to skip elements it considers non-contentful: zero-opacity elements, full-viewport overlays, and low-entropy placeholder images.
When the LCP element is an image, the time splits into four parts:
- Time to first byte — server and network before the HTML arrives
- Resource load delay — the gap between the HTML arriving and the browser starting to fetch the image
- Resource load duration — downloading the image
- Element render delay — the gap between the image finishing and it actually painting
Most WordPress sites with bad LCP have their problem in load delay, not load duration. The image is discovered late because it is a CSS background, or it is lazy-loaded when it should not be, or it sits behind a render-blocking stylesheet. Compressing that image further does nothing for load delay. This is why “we converted everything to WebP and LCP didn’t move” is such a common outcome — and it is covered from the image side in our post on why website speed matters.
WordPress core has shipped automatic fetchpriority="high" on the image it guesses is the LCP element since 6.3, with the logic centralised in wp_get_loading_optimization_attributes() and made filterable in 6.4. On page-builder sites the guess is frequently wrong, because the visually largest element is often a CSS background in a Elementor or Divi section rather than a content image core can see. The WordPress Performance Team’s Optimization Detective and Image Prioritizer plugins exist specifically to replace that guess with real client-side measurement.
INP: three sub-parts, and the fix depends on which one
INP splits into input delay (time before any callback for the interaction runs), processing duration (time for all callbacks to execute), and presentation delay (time after callbacks until the frame paints). The three have completely different causes:
| Dominant sub-part | Typical WordPress cause | What actually fixes it |
|---|---|---|
| Input delay | Main thread busy with third-party tags, analytics, chat widgets, A/B test scripts | Defer or remove scripts; move tags server-side; audit tag manager |
| Processing duration | Heavy jQuery handlers, plugin event listeners bound to every element, unoptimised AJAX add-to-cart | Break up long tasks, debounce, remove duplicate handlers |
| Presentation delay | Large DOM, expensive CSS recalculation, layout thrash on state change | Reduce DOM size, use CSS containment, avoid forced synchronous layout |
INP reports the worst interaction on pages with few interactions. On high-interaction pages it discards one outlier per 50 interactions, so a single bad frame on a busy page does not define your score — but a consistently slow add-to-cart button on a WooCommerce product page absolutely will.
CLS: it is the worst burst, not the total
A common misreading: CLS is not the sum of every shift on the page. It is the largest session window — a burst of shifts with less than one second between each, capped at five seconds total. Your score is the highest-scoring single burst across the page’s lifetime.
Shifts within 500 ms of a discrete user interaction (a tap, a click, a keypress) are flagged hadRecentInput and excluded. That exclusion does not apply to continuous gestures, so a layout shift triggered during scroll or pinch-zoom counts against you.
On WordPress the offenders are predictable: cookie banners injected above the fold after paint, ad slots without reserved height, web fonts swapping and reflowing text, and images lacking width and height. Core adds dimensions automatically, but the problem reappears whenever a theme or builder outputs images through its own markup.
A measurement setup that reflects what Google sees
Three layers, in order of how much they should influence your decisions:
- Search Console’s Core Web Vitals report — this is CrUX data grouped into URL patterns. It is the closest thing to seeing what Google sees, and it is free. Start here.
- PageSpeed Insights on specific URLs — gives you the CrUX field data for that URL if it exists, and the origin fallback if it does not. Read the field section; treat the lab score as a debugging hint.
- Real user monitoring — the
web-vitalsJavaScript library reports all three from your own visitors, with attribution data naming the element and sub-part responsible. This tells you why rather than whether, and it is small enough to paste into a theme:
import {onLCP, onINP, onCLS} from 'web-vitals/attribution';
function send(metric) {
navigator.sendBeacon('/wp-json/your-endpoint/v1/vitals', JSON.stringify({
name: metric.name,
value: metric.value,
rating: metric.rating,
target: metric.attribution.target // the element responsible
}));
}
onLCP(send);
onINP(send);
onCLS(send);The attribution build is the part that matters. Knowing your INP is 480 ms tells you nothing actionable. Knowing it is 480 ms and the target is the add-to-cart button, with most of it in processing duration, tells you exactly which handler to open.
What to do first
If you have a failing Core Web Vitals report and a fixed budget, the order is:
- Confirm you have field data. If Search Console shows no data, you are optimising against a simulation. Fix that first, or accept that you are flying blind.
- Find which metric fails, and on which device class. Mobile and desktop are assessed separately. Most failures are mobile-only.
- For LCP, find the sub-part. Load delay and load duration need completely different fixes and the wrong one costs you weeks.
- For INP, find the element. It is almost always one widget, one handler, or one third-party tag.
- Re-measure after 28 days, not after 28 minutes. The field window is rolling. A deploy today shows up gradually.
What makes this expensive is not the fixes. It is doing them in the wrong order — compressing images when the problem is load delay, buying a caching plugin when the problem is INP, migrating hosts when the problem is a chat widget.
If your Search Console report has been amber for months and you are not sure which of the three metrics is the real problem or which pages are actually affected, send us the URL and we will tell you which metric is failing and why before you commit to any work.
Related reading: why WooCommerce slows down after 10,000 products, where the INP and LCP failure modes above show up in their most expensive form.
