Lighthouse, CrUX and RUM: which Core Web Vitals data to use
Lighthouse, CrUX and RUM measure different things. Where each comes from, the LCP, INP and CLS thresholds, and which to use to prioritize, debug and track.
On this page 16 min read
- What the Core Web Vitals are today
- Three data sources that answer different questions
- Why the Lighthouse score does not match field data
- Which data to use for each decision
- How to find the cause of poor LCP, INP and CLS
- Why CrUX and RUM never match exactly
- Practical recommendations
- How to measure with WebVyze
Use CrUX to find out whether the site passes Core Web Vitals and to decide what to tackle first: it is the real-user data from Chrome that Google uses in Search. Use Lighthouse (or the lab part of PageSpeed Insights) to reproduce a problem and test the fix before you ship. Use your own RUM when you need to see each visit, each page and the cause of a bad number, with breakdowns CrUX does not offer. Lighthouse's 0 to 100 score is not a Core Web Vital and does not decide rankings on Google.
This article compares the three sources. For the basics of the metrics and how to improve each one, see the Core Web Vitals guide.
What the Core Web Vitals are today
There are three metrics, all with stable status according to web.dev:
LCP (Largest Contentful Paint) measures loading. It is the time until the largest image, text block or video visible in the viewport appears on screen (web.dev).
INP (Interaction to Next Paint) measures responsiveness to user actions. It observes the latency of clicks, taps and key presses throughout the visit and generally reports the worst; on pages with many interactions, it discards the highest one in every 50 so isolated cases do not skew it. Scrolling, hover and zoom do not count, and visitors who do not interact with the page produce no INP (web.dev).
CLS (Cumulative Layout Shift) measures visual stability. Unexpected shifts are grouped into windows (less than 1 second between shifts, up to 5 seconds per window), and CLS is the largest of these windows over the whole life of the page (web.dev).
INP replaced FID in March 2024
INP became a stable Core Web Vital in March 2024, replacing FID (First Input Delay). In the same announcement, Chrome began deprecating FID and gave anyone reading FID from the CrUX and PageSpeed Insights APIs until September 9, 2024 to move to INP (web.dev). The web-vitals library removed the onFID() function in version 5.0.0, released in May 2025 (web-vitals changelog). A report that still treats FID as a Core Web Vital is out of date.
The "good" thresholds and the 75th percentile rule
A page passes when the 75th percentile of page loads, split between mobile and desktop, is within the "good" threshold for all three metrics (web.dev). In other words, at least three out of every four visits need to have a good experience. PageSpeed Insights follows the same rule and only passes the assessment when all three 75th percentiles are good (PageSpeed Insights documentation).
| Metric | What it measures | Good | Needs improvement | Poor | Core Web Vital? |
|---|---|---|---|---|---|
| LCP | Loading of the largest visible element | up to 2.5 s | over 2.5 s up to 4 s | over 4 s | Yes |
| INP | Response time to interactions | up to 200 ms | over 200 ms up to 500 ms | over 500 ms | Yes |
| CLS | Visual stability (unitless score) | up to 0.1 | over 0.1 up to 0.25 | over 0.25 | Yes |
| FCP | First content on screen | up to 1.8 s | over 1.8 s up to 3 s | over 3 s | No |
| TTFB | Time to the first byte of the response | up to 0.8 s | over 0.8 s up to 1.8 s | over 1.8 s | No |
Sources for the thresholds: PageSpeed Insights, LCP, INP, CLS, FCP and TTFB.
FCP and TTFB help with diagnosis, but they are not Core Web Vitals
FCP (First Contentful Paint) marks the moment the first piece of content appears on screen: text, an image, an SVG or a non-white canvas (web.dev). TTFB (Time to First Byte) adds up redirects, service worker startup, DNS lookup, connection and TLS negotiation until the first byte of the response arrives (web.dev).
web.dev treats both as supporting metrics, useful for understanding a high LCP (web.dev). The TTFB article itself says that, since it is not a Core Web Vital, staying within the "good" threshold is not mandatory, as long as TTFB does not prevent good scores on the metrics that count (web.dev). In CrUX, TTFB is still listed as experimental: in the API, its name is experimental_time_to_first_byte (CrUX API).
Three data sources that answer different questions
Lab: Lighthouse and the diagnostics part of PageSpeed Insights
Lab data (also called synthetic data) comes from a simulated page load in a controlled environment. In PageSpeed Insights, Lighthouse does this part: on mobile, it simulates a mid-range device on a mobile network; on desktop, a computer with a wired connection (PageSpeed Insights). It is a single load, with one fixed device and network.
Lighthouse does not measure INP, because nobody is clicking on the page. The lab stand-in is TBT (Total Blocking Time), which measures how long the main thread is blocked during loading (web.dev). A good TBT does not guarantee a good INP: it leaves out, for example, the delay of the tap itself (web.dev).
The performance score, from 0 to 100, is a weighted average of five metrics. Using the weights the documentation publishes for Lighthouse 10, TBT counts for 30%, LCP and CLS for 25% each, and FCP and Speed Index for 10% each. Each metric is turned into points using a log-normal curve derived from real HTTP Archive data. The score varies between runs, and the documentation attributes much of this variation to changes in test conditions rather than to Lighthouse itself (Lighthouse documentation).
Field: Chrome UX Report (CrUX)
CrUX is the public dataset of real Chrome user data maintained by the Web Vitals program. According to Chrome, Google Search uses it in the page experience ranking factor (CrUX). It is the same data shown in the field part of PageSpeed Insights and in the Search Console Core Web Vitals report (Search Console Help).
It only includes Chrome users who have turned on usage statistics reporting, sync their history and do not use a sync passphrase. This covers Chrome on desktop (Windows, macOS, ChromeOS and Linux) and on Android, including Custom Tabs and WebAPKs. Chrome on iOS, Android apps that open pages in a WebView and other Chromium-based browsers, such as Edge, are left out. Google does not publish what fraction of users meets these criteria (CrUX methodology).
The origin and each page must be publicly discoverable, under the same indexing criteria search engines use (status 200 after redirects, no noindex), and "sufficiently popular". The minimum number of visitors is not disclosed (CrUX methodology). As a result, low-traffic pages, logged-in areas and staging environments have no field data.
Origin data combines all pages on the origin; URL data shows only that page (CrUX API). When the URL does not have enough data, PageSpeed Insights shows the origin's data, and if the origin has none either, it shows no field data (PageSpeed Insights).
The values are a rolling average of the last 28 days, and each access method updates at a different pace:
The CrUX API updates every day, around 04:00 UTC, with no guaranteed time, and runs about two days behind the current date (CrUX API).
The CrUX History API updates on Mondays and keeps up to 40 weekly periods, each with 28 days of data (CrUX History API).
BigQuery gets one table per month, published on the second Tuesday of the following month, with origin data only and history going back to 2017. It is the only access method with a country dimension (CrUX on BigQuery, tools comparison).
Your own RUM: measuring every visit to your site
RUM (real-user monitoring) is a script installed on the site that measures the metrics in each visitor's browser and sends the values to your own server or a vendor's. One way to measure with the same rules as Chrome is the web-vitals library from the Chrome team, which, according to its README, measures the metrics the same way Chrome and Google's tools do. It provides the functions onLCP, onINP, onCLS, onFCP and onTTFB and takes about 3 KB with brotli compression. The latest version at the time of writing is 6.2.3, released on October 5, 2026 (changelog).
What RUM gives you that CrUX does not:
Data for any page that has the script, including pages that fall below the CrUX traffic minimum and pages that are not public, without waiting for a 28-day window.
The cause of the number. The attribution build (
web-vitals/attribution, about 1.5 KB more) adds the element and the timing phases to each metric. For LCP, you get the element's selector and the four parts of the time; for INP, the element of the interaction, the three phases and the Long Animation Frames entries (which point to the scripts involved); for CLS, the element that shifted most and the loading phase in which it happened (web-vitals README).Breakdowns by page type, device, connection, country or any other data you send along (web.dev).
Other browsers:
onLCP,onINP,onFCPandonTTFBwork in Chromium, Firefox and Safari;onCLSworks only in Chromium (web-vitals README).
The documentation points out a few precautions. Data should be sent on the visibilitychange event, when the page becomes hidden, with navigator.sendBeacon(), because unload and beforeunload are not reliable. CLS and INP only settle their value when the page is hidden, and the same metric can be reported more than once (README, web.dev). To summarize, use percentiles rather than averages (web.dev). Consent banners and blockers remove visits from the sample, sometimes precisely the first page load, which tends to be the slowest, and a sampling rate that is too low distorts the numbers (web.dev).
SPAs and soft navigations: what changed in 2026
In single-page applications (SPAs), switching routes without reloading the page is a soft navigation. Browser APIs did not treat this switch as a navigation, and CrUX did not count it (web.dev). Starting with Chrome 151, it can be measured: a soft navigation is recorded when there is a user interaction, the URL changes and something is painted on screen. web-vitals added support for this in version 6.0.0, released in July 2026, with the reportSoftNavs: true option (README, changelog).
The library lists its own caveats. The definition can produce false positives. The TTFB of a soft navigation is reported as 0. Elements that stay on screen between routes do not count toward LCP, because they are not painted again. INP and CLS restart with each soft navigation. Turning the option on also changes how the first page load is measured, and browsers outside Chromium keep reporting only full page loads (web-vitals README).
In CrUX, experimental versions of LCP, INP and CLS that include soft navigations (for example, experimental_interaction_to_next_paint_with_softnavs) started shipping in October 2026 in the API, the History API and BigQuery. The stable Core Web Vitals did not change. Chrome plans to take the new metrics out of experimental status in May 2027, depending on the feedback it receives, and only after that will Search Console start using them. According to the announcement, the difference is concentrated in SPAs with many navigations after the first one; for most sites, the numbers should change little or not at all (web.dev, web.dev).
Comparing lab, CrUX and RUM
| Lab (Lighthouse) | Field: CrUX | Field: your own RUM | |
|---|---|---|---|
| Where the data comes from | One simulated page load, with a fixed device and network | Real Chrome users who meet the inclusion criteria | A script on your site, measuring the visitors it reaches |
| Coverage | Any page the tool can open | Only public origins and pages with enough traffic; Chrome only, no iOS | Every page with the script; multiple browsers (CLS only in Chromium) |
| Delay | None: results right away | 28-day average; daily API about 2 days behind, weekly History API, monthly BigQuery | Depends on the tool; no need to wait 28 days |
| Granularity | One page load, with audits and a performance trace | Origin and URL (API, PageSpeed Insights); URL groups (Search Console); origin only (BigQuery); by device type | Each visit, with element and phases when attribution is on |
| INP | Does not measure it; uses TBT as a stand-in | Measures it | Measures it |
| Good for | Debugging, testing before you ship, comparing two versions | Knowing whether the site passes, prioritizing, comparing with competitors; it is the data Google uses | Finding the cause, segmenting, seeing the effect of a deploy within a few days |
| Limits | Does not represent the range of users; empty cache; CLS and LCP only from the load; score fluctuates between runs | Does not point to the cause; no data for low-traffic pages; slow to reflect a fix | Depends on consent and sampling; requires installing and maintaining the script; not the data Google uses |
Why the Lighthouse score does not match field data
web.dev lists the reasons (web.dev):
The lab uses one device, one network and one location. Your users use many, and the field 75th percentile reflects that mix.
The lab test usually loads the page with an empty cache. Returning visitors already have files cached and see the page faster.
The test's LCP element may not be the one the user sees. Screen size, personalization and A/B tests change which element is largest.
In the field, the browser stops looking for larger elements as soon as the user scrolls or interacts, which can produce a lower LCP.
In the field, CLS counts shifts throughout the visit. The lab captures almost only what happens at the top of the page during loading, and misses, for example, images and iframes without dimensions that only load when the user scrolls.
Targeted ads and A/B tests change what loads for each person.
web.dev's own recommendation is to use field data to set priorities and lab data to debug and test before you ship (web.dev).
A good Lighthouse score does not guarantee a ranking on Google
What Google Search Central says (page experience, Core Web Vitals in Search):
Core Web Vitals are used by the ranking systems, but there is no single page experience signal.
Good results in the Search Console report or in third-party tools do not guarantee that pages will rank at the top of Search.
Search tries to show the most relevant content, even when the page experience is subpar.
Chasing a perfect score purely for SEO reasons may not be the best use of your time.
The Search Console Core Web Vitals report comes from CrUX (Search Console Help), not from the Lighthouse score. What appears there is the experience of real users, not the result of a lab test.
Which data to use for each decision
The table below is our own recommendation, built from the characteristics of each source described above.
| Decision | Data | Why |
|---|---|---|
| Does the site pass Core Web Vitals? | CrUX (Search Console, field part of PageSpeed Insights) | It is the data in the Search Console report and it uses the 75th percentile rule |
| Which pages should we tackle first? | Search Console URL groups; RUM by page type | Per-URL CrUX data is missing for low-traffic pages; RUM covers every page that has the script |
| Why is this page's LCP high? | RUM with attribution; then the lab to reproduce it | Attribution shows the element and which of the four parts of the time weighs most |
| Which interaction makes INP poor? | RUM with attribution; then DevTools | Lighthouse does not measure INP, and TBT does not point to the interaction |
| Does the fix work before we ship? | Lighthouse or DevTools, run several times before and after | It is the only data available before the deploy; the score fluctuates between runs |
| Did the fix work for users? | RUM in the following days; CrUX over 28 days | RUM shows the effect first; CrUX confirms it in the data Google uses |
| How do we compare with competitors? | CrUX | It has data for any public origin with enough traffic |
| How are the logged-in area and checkout doing? | RUM | CrUX only includes publicly discoverable pages |
When the table does not apply: if the site has no CrUX data and you have not installed RUM yet, the lab is the only signal available. In that case, use it to find obvious problems, knowing it does not tell you whether users pass the thresholds.
How to find the cause of poor LCP, INP and CLS
The path Google recommends starts in the field and then moves to the lab: if there is CrUX data, look at real users first (web.dev); for INP, collect field data, reproduce the slow interaction in the lab and only then optimize (web.dev). Below is a summary of how each metric breaks down. Each one has its own article with the fixes.
LCP: the four parts of the time
TTFB: from the start of the page load until the first byte arrives. Google's reference: about 40% of LCP.
Resource load delay: from TTFB until the browser starts downloading the LCP resource (the image, for example). Less than 10%.
Resource load duration: the time to download that resource. About 40%.
Element render delay: from the end of the download until the element is fully displayed. Less than 10%.
web.dev calls these proportions a reference, not a rule (web.dev). For image LCPs, the CrUX API already provides these four parts and the LCP resource type; BigQuery does not have this data (CrUX API, tools comparison). The fixes for each part are in how to improve LCP.
INP: the three phases of an interaction
Input delay: from the moment of the interaction until the event callbacks start running. It grows when the main thread is busy with other scripts.
Processing time: how long the event callbacks take to finish.
Presentation delay: from the end of the callbacks until the browser paints the next frame with the result.
web.dev suggests reproducing the slow interaction in the lab by interacting with the page while it loads, when the main thread is usually busiest (web.dev). In RUM, web-vitals attribution reports the duration of each phase and the Long Animation Frames entries linked to the interaction (README). The step-by-step process is in how to improve INP.
CLS: the element that moves
The most common sources, according to web.dev, are images, ads, embeds and iframes without dimensions, content injected after loading, web fonts and animations of properties such as top and left instead of transform. Shifts that happen within 500 ms of a click, tap or key press are treated as expected and do not count. Making the page eligible for the back/forward cache (bfcache) keeps shifts from repeating when the user goes back (web.dev, web.dev).
To find the element: in the field, web-vitals attribution reports the element that shifted most; in the lab, the DevTools Performance panel shows the layout shift records, and Lighthouse lists the elements that moved and the images without width and height (web.dev). More details in how to fix CLS.
Why CrUX and RUM never match exactly
Even though both measure real users, the two sources cover different populations and windows: CrUX is Chrome only and eligible users only; RUM depends on consent, on sampling and on when the script sends the values. web.dev considers small differences normal and suggests, for comparison, filtering RUM to Chrome, the same device type, the 75th percentile and a 28-day window. For day-to-day use, the advice is to watch the trend after each change, without expecting the numbers to match (web.dev).
Practical recommendations
What follows is our opinion, based on the facts above.
Start with the Search Console Core Web Vitals report or the field part of PageSpeed Insights. That is the data that shows whether the site passes the thresholds.
If the site or the pages that matter have no CrUX data, install RUM before spending time trying to raise the Lighthouse score.
In RUM, use the attribution build of web-vitals and send the page type along (product, category, article). That way you can see whether the problem belongs to a whole page template or to a single URL. To do this across many sites at once, see how to monitor the performance of multiple sites.
Use Lighthouse to test fixes, running it more than once before and after. A single run is not enough to conclude anything.
If the site is an SPA, Google itself suggests starting to measure Core Web Vitals per route now (web.dev). That shows you early what may change when the soft navigation metrics stop being experimental.
These recommendations do not apply if you need the Lighthouse score because of a contract or a client requirement. In that case, the score is the requirement, even with no direct effect on Search.
How to measure with WebVyze
The Core Web Vitals test is free and shows CrUX data for the last 28 days, on mobile and desktop, for up to 10 URLs. The free LCP, CLS and INP diagnostics use Google PageSpeed. The paid plans, starting with Starter, include a real-visitor script that measures LCP, INP and CLS for each visit with Google's web-vitals library and points to the element or the cause.
Frequently asked questions
- Does CrUX have separate data for tablets?
- Yes. The CrUX API accepts three form factors: PHONE, DESKTOP and TABLET. If none is given, the query returns the combined data for all devices. To compare with Search Console, which assesses mobile and desktop separately, filter the form factor in the query.
- Do URL parameters, such as UTM tags, create separate pages in CrUX?
- No. According to the CrUX methodology, the query string and the fragment (the part after #) are removed from the URL. A visit to /product?utm_source=x counts as a visit to /product.
- Does content inside an iframe count toward LCP and CLS?
- In CrUX, yes: iframes do not appear as pages of their own, and their metrics are counted in the main page. In JavaScript-based RUM, the page's script cannot see the content of cross-origin iframes, so LCP and shifts that happen inside an embedded video, for example, may be missed. That is why CrUX can show worse numbers than RUM on pages with many embeds.
- Do Search Console and PageSpeed Insights use the same data?
- Both use CrUX data from the last 28 days, but in different ways. PageSpeed Insights shows a URL (or the origin, when the URL lacks data). Search Console puts similar URLs into groups, gives each group the status of its worst metric for that device type and keeps about three months of history. A group needs enough LCP and CLS data to appear in the report.
- Why does my RUM show worse numbers than CrUX, even when I filter for Chrome only?
- One possible cause is the back/forward cache (bfcache). CrUX counts a page restored from this cache as a navigation, but browser APIs do not treat that restore as a page load. According to web.dev, RUM that leaves these restores out can show worse numbers than CrUX. The web-vitals library treats the restore as a new measurement, with a different id.
See what your site needs to fix.
A free check by law, with the cause and the fix guide for each problem.
Keep reading
- Technical SEO
AI crawlers in robots.txt: search, user access and training
GPTBot, ClaudeBot, OAI-SearchBot, Google-Extended: what each AI crawler does, whether it respects robots.txt, and how to block training but stay in search.
- Technical SEO
Redirects: chains, loops and how to fix them
How Google handles 301, 302, 307 and 308, what chains and loops do to crawling and speed, and how to map, fix and test your redirects.
- Technical SEO
llms.txt: what it is, what it doesn't do and how to create one
llms.txt summarizes a site for AI agents. See the format, what Google and other companies say about it, when it's worth creating and how to write a good one.