Performance
Understanding page speed: what the numbers mean and which one counts
This article explains which values there are, what they measure, why two measurements of the same page give different results and in which order work pays off.
11 min read
By Timo Wessels Published Updated
"My website scores 47." That is the sentence this topic usually starts with. And it is the wrong place to start — because the score is the result and not the cause, and because it comes out differently depending on how it was measured.
For context first: in the HTTP Archive's analysis for 2024, only 43 percent of websites reached good results in all three core metrics on mobile, and 54 percent on desktop. So on mobile, more than half of all websites miss the mark. It is not a niche problem, and a bad result is no reason for a bad conscience.
Why page speed matters
Three effects that belong together:
Visitors leave. A slow page feels broken. The visitor cannot tell whether anything else is coming and goes back to the search results — before reading a word of what you offer.
Search engines take it into account. Google itself says that good core metrics are in line with what its ranking systems aim to reward. That is no guaranteed top spot — but it is a factor you can influence directly, unlike much else.
It hits mobile users first. And for most businesses they are the majority. If you only test on an office computer with fibre, you never see the problem.
And a connection you rarely hear about: almost everything that improves page speed also improves maintainability and security. Fewer scripts means fewer things that can break. Fewer plugins means less attack surface.
The three core metrics
Google bundles three measurements meant to capture how good a page feels — the Core Web Vitals. Each measures something different. What counts is not the average but the value that three quarters of all page views reach or beat, measured separately for mobile and desktop.
LCP — Largest Contentful Paint
What is measured: how long it takes until the largest visible element in the first screen is displayed. Usually a large image or the main heading.
What the visitor experiences: when the page is "there". Not finished loading — but visible.
| Rating | Value |
|---|---|
| good | up to 2.5 seconds |
| needs improvement | 2.5 to 4 seconds |
| poor | over 4 seconds |
The three causes that have stayed the same for years: oversized images, render-blocking resources in the page head, a slow server response.
CLS — Cumulative Layout Shift
What is measured: how much the page still moves while it loads.
What the visitor experiences: they want to tap a link, at that very moment an image loads further up, everything slides down, and they tap something else. This is the metric that causes the most genuine anger — on a phone especially.
| Rating | Value |
|---|---|
| good | up to 0.1 |
| needs improvement | 0.1 to 0.25 |
| poor | over 0.25 |
The cause is almost always the same: missing dimensions. Images without width and height, banners that load late, cookie notices that push the content down, and fonts that wrap the lines differently when they replace the fallback font.
Easy to fix — and still ignored most often, because it hardly ever shows on a developer's machine with a fast connection.
INP — Interaction to Next Paint
What is measured: how quickly the page responds to an input. Across the whole visit, not only while loading.
What the visitor experiences: they tap a menu item, nothing happens for half a second, so they tap again.
| Rating | Value |
|---|---|
| good | up to 200 milliseconds |
| needs improvement | 200 to 500 milliseconds |
| poor | over 500 milliseconds |
Important: on 12 March 2024, INP replaced the earlier metric FID. FID only measured the very first interaction during loading; INP measures across the whole session. Any guide that still talks about FID is out of date.
And a limit that tools rarely name: INP cannot be measured at all without real interaction. A lab measurement reports the Total Blocking Time instead — the time the main thread was blocked during loading. Google itself calls it a reasonable stand-in, but not an equivalent.
The cause is usually JavaScript from plugins that load on every page although they are only needed on one.
The other values in the report
TTFB — Time to First Byte. How long the server takes until the first byte arrives. This happens before everything else: TTFB is the first part of LCP, and every tenth of a second the server needs is added on top of every other value. Google calls 0.8 seconds or less good and over 1.8 seconds poor.
This value depends on hosting and server configuration. Image optimisation cannot improve it.
FCP — First Contentful Paint. When the first element becomes visible at all. Good is up to 1.8 seconds.
TBT — Total Blocking Time. How long the browser's main thread was blocked by JavaScript. The lab stand-in for INP.
DOM size. Not a time but a count: how many elements the page has. Lighthouse warns from about 800 elements and reports an error from about 1,400. This value regularly explodes on page-builder sites, because every building block brings several nested containers along.
The point almost everyone gets wrong: lab versus real life
PageSpeed Insights gives you two different data sets. This is the most common source of confusion on the whole topic.
Field data is at the top: real measurements from real visitors to your page over the last 28 days, collected by Chrome in the Chrome User Experience Report. What is shown is not the average but the value 75 percent of your visitors reach or beat. That is reality.
Lab data is below it: a single measurement, run just now, under artificially throttled conditions. For mobile it simulates a mid-range phone on a mobile network. That is the diagnosis.
Three conclusions:
When the two disagree, the field wins.
Field data is often missing. It needs enough visitors. For small websites there is simply nothing there — not an error, but a sign that the assessment has to rely on the lab measurement.
The lab measurement is deliberately pessimistic, and it fluctuates. It throttles processing power and connection, so it typically comes out well below a measurement on your own machine, and two runs in a row do not give the same result. Google itself advises thinking of performance as a distribution rather than a single number. A jump of a few points is not an improvement, it is fluctuation.
And one point that matters for AI visibility: field data comes from people visiting your page in Chrome. It does not measure how quickly your server answers a crawler in a data centre. A good PageSpeed score therefore says nothing about whether an AI crawler gets your page in time. Those are two different questions.
The score is not the goal
The big number at the top is a weighted blend. Useful as a rough bearing, misleading as a target.
It hides what is going on. Two pages with the same score can have completely different problems — one a slow server, the other too much JavaScript. The fixes are opposite.
The last points are the most expensive. On Google's own scoring curve, going from 99 to 100 takes as much improvement as going from 90 to 94. The work that pays off for your visitors lies further down.
It can be optimised without making the page faster. Declare the number the goal and that is exactly what you get.
My benchmark: the three core metrics in the green, and the page feels good on an average phone on an average network.
How to measure it yourself
PageSpeed Insights at pagespeed.web.dev. Enter the address, done. Always start with mobile — that is where there is most to gain. More interesting than the score is the "Diagnostics" section: it shows which specific files cost how much time.
Lighthouse in the developer tools. Right-click, Inspect, Lighthouse tab. Good for trying things while you work. Poor for comparisons, because your machine and your network affect the result.
The Network tab with throttling. Throttle the connection to a slow mobile connection and reload the page. The best tool for tracking down layout shifts: in slow motion you can see exactly which element loads late and pushes everything around.
Search Console. Its Core Web Vitals report shows your website's field data grouped into pages that behave alike — so which group of pages has problems, not just a single page. Here too: no data without enough visitors.
Without any tool: your own phone, Wi-Fi off, open the page, count. That is the experience your customers have. And for CLS watching is enough: reload and see whether anything jumps.
What to do — ordered by impact
The order matters more than the list.
1. Images. Almost always the biggest single item and the best return on effort.
- convert to a modern format (WebP or AVIF)
- scale to the size they are actually shown at — no huge camera photo in a small area
- set up automatic compression on upload so the problem does not come back
- set
widthandheightso the space is reserved and nothing shifts - use
srcsetandsizesso small screens get small files - lazy-load images below the visible area
- explicitly do not lazy-load the large image at the top, give it
fetchpriority="high"instead — otherwise you make worse the very value you wanted to improve
2. Server response time. When TTFB is high, nothing else helps. Check: page cache active, current PHP version, OPcache on, compression on, HTTP/2 or HTTP/3. If all of that is right and the value stays high, the hosting is too weak or the database is overloaded.
3. Plugins. The underestimated item. Every plugin brings its own scripts and styles, and many load them on every page — even where they do nothing. A form plugin loads its files on the home page although the form is only on the contact page.
The most effective step is not optimising a plugin, it is removing it.
4. Fonts. From your own server instead of someone else's, reduced to the characters you need, in WOFF2, as few weights as possible, loaded so the text is visible immediately. This also has a data protection side when the font would otherwise load from a third-party server.
5. Delivery. Two server settings, no content work:
- Compression for text files (HTML, CSS, JavaScript) with Gzip or Brotli. Images, fonts and videos are already compressed — compressing them again costs processing time and gains nothing.
- Cache headers with long lifetimes for static files, so a returning visitor does not download them again.
6. CSS and JavaScript. Remove what is not needed, minify the rest, defer non-critical scripts, deliver critical CSS for the visible area inline. The area with the most technical effort and the lowest return per hour — which is why it comes last.
7. Tidying up WordPress. Switch off the emoji script, limit unnecessary embeds, limit revisions, clean up the database. Small effects one by one, noticeable together.
What I tell clients to expect
Page speed is not a project with an end date. It gets worse with every new plugin, every embedded service and every large image someone uploads. A website optimised once is back where it started after a while without attention. That is why measuring belongs in ongoing maintenance.
Most of the result comes from a few decisions: how many third-party services are embedded, how the theme is built, how many plugins run. Get those three right and you usually do not need the fine-tuning at all.
And the uncomfortable truth about old websites: if a site runs a great many plugins and comes from a page builder that wraps every section in several nested containers, optimisation is treating symptoms. Then the question is whether a rebuild is not the cheaper way.
Sources
- HTTP Archive, Web Almanac 2024, Performance chapter — share of websites with good Core Web Vitals: almanac.httparchive.org
- web.dev, Web Vitals — the three core metrics and the 75th percentile: web.dev/articles/vitals
- web.dev, Largest Contentful Paint: web.dev/articles/lcp
- web.dev, Cumulative Layout Shift: web.dev/articles/cls
- web.dev, Interaction to Next Paint: web.dev/articles/inp
- web.dev, INP replaces FID on 12 March 2024: web.dev/blog/inp-cwv-march-12
- web.dev, Time to First Byte: web.dev/articles/ttfb
- web.dev, First Contentful Paint: web.dev/articles/fcp
- web.dev, Optimize LCP — the parts of LCP and
fetchpriority: web.dev/articles/optimize-lcp - web.dev, lazy-loading the LCP image: web.dev/articles/lcp-lazy-loading
- Chrome for Developers, DOM size in Lighthouse: developer.chrome.com
- Chrome for Developers, Lighthouse scoring and variability: developer.chrome.com
- Google, About PageSpeed Insights — field data and lab data: developers.google.com
- Google Search Central, Core Web Vitals and Google Search: developers.google.com
- Search Console Help, Core Web Vitals report: support.google.com