PageSpeed Insights shows two reports. The top one is field data from real Chrome visitors over the last 28 days, judged at the 75th percentile. The lower one is a Lighthouse lab test with a 0 to 100 score: 90 or more is good, 50 to 89 needs work, under 50 is poor. Fix field metrics first.
| Metric | Good | Needs improvement | Poor |
|---|---|---|---|
| LCP (Largest Contentful Paint) | 2.5 s or less | 2.5 to 4 s | over 4 s |
| INP (Interaction to Next Paint) | 200 ms or less | 200 to 500 ms | over 500 ms |
| CLS (Cumulative Layout Shift) | 0.1 or less | 0.1 to 0.25 | over 0.25 |
| FCP (First Contentful Paint) | 1.8 s or less | 1.8 to 3 s | over 3 s |
| TTFB (experimental) | 0.8 s or less | 0.8 to 1.8 s | over 1.8 s |
Updated
Most people stare at the big circular score, but that number comes from one simulated visit on a throttled phone. This guide separates the two halves of the report, lets you rate your own numbers against the official thresholds, and maps every red metric to the change that usually moves it.
Enter the values from your report to see whether each one is good, needs improvement or poor.
Lighthouse 10 and later combine five lab metrics. Total Blocking Time carries the most weight, so heavy JavaScript hurts the score more than anything else.
| Lab metric | Weight | Field metric it relates to |
|---|---|---|
| Total Blocking Time | 30% | INP |
| Largest Contentful Paint | 25% | LCP |
| Cumulative Layout Shift | 25% | CLS |
| First Contentful Paint | 10% | FCP |
| Speed Index | 10% | None directly |
| Audit or symptom | Why it is red | Usual fix |
|---|---|---|
| Largest Contentful Paint image was lazily loaded | The browser waits for layout before fetching the hero | Remove loading=lazy from the hero and add fetchpriority=high |
| Eliminate render-blocking resources | CSS or sync scripts in the head delay first paint | Inline critical CSS, defer scripts |
| Properly size images | Images are larger than their displayed size | Use srcset and sizes, export at display width |
| Serve images in modern formats | JPEG or PNG where AVIF or WebP would be smaller | Convert and serve with picture or an image CDN |
| Reduce unused JavaScript | Code shipped for features not on this page | Split bundles per route, drop unused libraries |
| Reduce the impact of third-party code | Tags block the main thread | Load tags after interaction or on idle |
| Image elements do not have explicit width and height | Space is not reserved, so content jumps | Set width and height or aspect-ratio |
| Ensure text remains visible during webfont load | Text is hidden while the font downloads | Use font-display: swap and preload the main font |
| Initial server response time was long | Slow TTFB from uncached HTML | Cache HTML at the edge, cut redirects |
No lazy loading on the likely LCP element, a high fetch priority, modern formats and real dimensions so nothing shifts.
<picture>
<source type="image/avif" srcset="/hero-800.avif 800w, /hero-1600.avif 1600w" sizes="100vw">
<source type="image/webp" srcset="/hero-800.webp 800w, /hero-1600.webp 1600w" sizes="100vw">
<img src="/hero-1600.jpg" alt="Kitchen renovation with oak cabinets"
width="1600" height="900" fetchpriority="high" decoding="async">
</picture>Preload the one font file used above the fold and let text show in a fallback until it arrives.
<link rel="preload" href="/fonts/inter-var.woff2" as="font" type="font/woff2" crossorigin>
<style>
@font-face {
font-family: "Inter";
src: url("/fonts/inter-var.woff2") format("woff2");
font-display: swap;
}
</style>Injects a marketing script once the browser is idle, so it does not compete with the first render or the first tap.
function loadLater(src) {
const add = () => {
const s = document.createElement("script");
s.src = src;
s.async = true;
document.head.appendChild(s);
};
if ("requestIdleCallback" in window) requestIdleCallback(add, { timeout: 4000 });
else setTimeout(add, 2000);
}
window.addEventListener("load", () => loadLater("https://example.com/tag.js"));An embed or ad slot with a fixed aspect ratio keeps the content below it from jumping when it loads.
.video-embed { aspect-ratio: 16 / 9; width: 100%; background: #f1f5f9; }
.ad-slot { min-height: 250px; }| Step | Check |
|---|---|
| 1 | Field data: which of LCP, INP and CLS fails at the 75th percentile? |
| 2 | LCP element: is it an image, and is it lazy loaded or discovered late? |
| 3 | TTFB: is the HTML cached, and are there redirects before it? |
| 4 | JavaScript: what is the Total Blocking Time and which scripts cause it? |
| 5 | Layout: do images, embeds and banners have reserved space? |
| 6 | Fonts: is font-display set and is the main file preloaded? |
The first block answers whether real visitors had a good experience. It shows the 75th percentile value for each metric, which means three out of four visits were at least that fast. Passing all three Core Web Vitals (LCP, INP and CLS) is the target.
The second block is a single Lighthouse run. Its diagnostics and opportunities are where you find out why a field metric is slow, because the lab trace lists the actual files, images and scripts involved.
Take a typical small business homepage with a full-width hero photo loaded lazily, a web font without a fallback strategy and three marketing tags in the head. In this example the LCP image only starts downloading after the script finishes, so LCP lands in the poor band.
Removing loading=lazy from the hero, adding fetchpriority=high, serving the photo as AVIF or WebP at the displayed size and moving the tags to load after the page is interactive attacks each LCP sub-part. Those are the changes shown in the code below; your own numbers will depend on your page.
LCP is split into four parts: time to first byte, resource load delay, resource load duration and element render delay. Find the biggest part first, then fix that one.
INP is about long JavaScript tasks running when someone taps or types. CLS comes from things that change size after first paint: images without dimensions, late banners and fonts that swap to a different width.
They measure different things. Field data is what real Chrome users on their own devices and networks experienced over 28 days. The lab score is one simulated load with fixed throttling. A page can score 60 in the lab and still pass Core Web Vitals in the field, or the reverse.
Google describes Core Web Vitals as measures of real-world user experience that line up with what its core ranking systems reward. Its Search guidance does not name the 0 to 100 lab score as a ranking input, so treat that score as a diagnostic for finding problems.
Time to First Byte is how long the browser waits before the first byte of the HTML arrives, including redirects, DNS, connection setup and server work. PageSpeed Insights treats 800 ms or less as good. Caching HTML at a CDN edge is the most common fix.
In Lighthouse 10 and later it is a weighted blend of five lab metrics: Total Blocking Time 30 percent, LCP 25 percent, CLS 25 percent, FCP 10 percent and Speed Index 10 percent. Each metric is first turned into a 0 to 100 sub-score on a curve.
The Chrome User Experience Report only publishes data for pages and origins with enough eligible visits. New or low-traffic sites often have none, so rely on the lab test plus your own monitoring until traffic grows.
Related: Core Web Vitals guide, Free website grader, How to optimize website speed, Web font loading, Optimize images for the web.
Start for free or see all free tools. We.Inc is free to start, with no card needed. AI building is on paid plans from $20 a month.
We.Inc is an AI-powered website builder you can resell under your own brand. Launch a branded client dashboard, bill on Stripe Connect, and deliver AI-generated websites in minutes. White-label plans start at $99 a month for 25 client sites, with a 7-day free trial and no per-site fees.