A 100 in PageSpeed Insights is one of the very few numbers in this job you can chase to a literal maximum, which is exactly why people chase it. It is a score, not a feeling, and getting it forces real fixes. It is also a lab score: one simulated load, on a fixed device and network profile, run once. Two of the three things that most determine whether a site feels fast to a real person are not in it at all. Here is what the number is made of, and what it never sees. What the 100 points are actually made of The performance score is a weighted average of five metrics, and the weights are not close to equal. Total Blocking Time is 30 per cent. Largest Contentful Paint is 25. Cumulative Layout Shift is 25. First Contentful Paint is 10. Speed Index is 10. TBT alone carries three times the weight of FCP, which is why two sites with an identical "feels fast" first impression can land twenty points apart. One of them has a script blocking the main thread for two seconds after that first paint, and the score punishes exactly that. Each metric is scored on its own curve, and the curve is not linear. Chrome's documentation puts it on a log-normal distribution built from real HTTP Archive data, with two fixed points: the 25th percentile of real sites scores 50, and the 8th percentile scores 90. Between roughly 50 and 92 the relationship is close to linear, so shaving time off a slow metric buys a predictable number of points. Above 96 it is not. The same time saved buys a fraction of a point. That is the mathematical reason the last few points cost disproportionately more than the first sixty, and it is a fact about the scoring function rather than about your code. Why the main thread does the most damage TBT measures every stretch of time the main thread is blocked for more than 50 milliseconds between First Contentful Paint and interactivity, added together. It is rarely one slow thing. It is a dozen small ones: a bundle that parses and executes before anything else can run, a chat widget loading eagerly, an analytics tag, a carousel library doing DOM work for something nobody has scrolled to. Each is harmless in a code review. Stacked, they are what a visitor experiences as a page that looks ready and does not respond when tapped. The fix is rarely "write faster code". It is mostly sequencing. Defer what is not needed for the first paint. Split the bundle so the browser is not parsing code for features below the fold. Load third-party scripts after first interaction rather than on page load, since none of them are why anyone came. Most sites lose more points to script execution than to image weight, even though images get blamed first and fixed first. Why the score moves when nothing changed A single Lighthouse run is a sample, not a measurement. Chrome's own scoring documentation lists A/B tests, ad-serving changes, shifting internet routing, device load, browser extensions and antivirus software as normal sources of run-to-run variance, before anything you deployed enters into it. Ninety-four one minute and eighty-eight the next is usually not a regression. It is the same page measured under slightly different conditions. Judge a trend across several runs rather than a single number somebody screenshotted for a status report. Desktop and mobile are also not one test with a label swapped. Since Lighthouse v6 they run on separate scoring curves calibrated to different real-world data, and mobile is throttled to a slower, more constrained profile deliberately. A page scoring 100 on desktop and 74 on mobile is not a bug in the tool. It is the tool doing the one thing it is for. The gap between a lab 100 and a good experience PageSpeed Insights shows lab and field data side by side and Google is explicit that it does not combine them. The 0 to 100 score is based entirely on the lab run. Field data from the Chrome UX Report is reported separately and does not touch that number. Their documentation states it about as plainly as documentation ever does: having good lab data does not necessarily mean real-user experiences will also be good. So a 100 tells you the simulated load on the tested device and network was excellent. It does not tell you what happened on a three-year-old Android phone on patchy 4G, which is where a meaningful share of real traffic actually lives. Core Web Vitals — field data at the 75th percentile of real visits over a rolling window — is the number Google's ranking systems actually read, and a site can hold 100 in the lab while failing it in the field. The metric the score does not contain at all Interaction to Next Paint is not in the performance score in any form, at any weighting. INP replaced First Input Delay as a Core Web Vital on 12 March 2024, and unlike FID it does not stop at the first interaction. It observes the latency of every click, tap and keypress across the whole lifespan of a visit and reports a single value representing roughly the worst of them. Good is 200 milliseconds or less at the 75th percentile; above 500 is graded poor. A lab run cannot produce that number honestly, because a lab run does not interact with the page. It loads it and stops. Chrome's guidance is explicit that a lab INP figure depends entirely on which interactions were performed during measurement, and that many lab tools do not report one at all. TBT is the closest proxy and it only covers the window around page load. The practical consequence is specific and very common: a page scores 100, and then a menu takes 600 milliseconds to open on a mid-range phone because an event handler does too much work per tap. The score never saw it, because nobody tapped anything. The navigations the score never sees either Chrome's usage data puts one in ten navigations on desktop and one in five on mobile as back or forward. Those, if you let them, are not loads at all — the back/forward cache keeps a paused snapshot in memory and restores it almost instantly with no network involved. PageSpeed Insights will never show you this. It is not part of the score on any run. It is, however, a large part of whether a site feels fast, and it is mostly a matter of not disqualifying yourself. Never use the unload event, which web.dev states about as plainly as it states anything — move that work to pagehide or to visibilitychange, which are more reliable on mobile anyway. Cache-Control: no-store may make a page ineligible. Open IndexedDB, fetch, WebSocket or WebRTC connections will do it, as will a non-null window.opener. DevTools will test a page and name the reason it failed. Fixing this is usually deleting something rather than building something, which makes it the cheapest performance work available and the easiest to never get round to. The order the fixes actually go in Measure several runs first, so you are optimising a range rather than an outlier. Then TBT, because it is 30 per cent of the score and almost always the largest single loss. Then LCP — and identify what the largest element actually is, because it is frequently a heading in a webfont rather than the hero image everyone assumes. Then CLS, which is usually the cheapest of the three: explicit dimensions on images and embeds, reserved space for anything injected late, and a font strategy that does not reflow. Only after those three sit green is the 94-to-100 gap worth anyone's time, and by then it is two or three specific items rather than a project. And be selective about where you spend it. The log-normal curve makes the last few points the most expensive on the page by a wide margin, and Chrome's own colour banding draws no distinction between 90 and 100 — both are simply "good". The homepage and paid landing pages can earn the last mile. A blog post two clicks deep will not. Read the full version This is the condensed version. The full article has the metric-by-metric breakdown with what moves each one, the full scoring-curve explanation, and the questions clients ask when the number and the experience disagree. How to Get a 100 PageSpeed Score, and What It Means Sources The metric weights, the log-normal curve and the sources of run-to-run variance are documented in Lighthouse performance scoring. That the displayed score is lab-only, and that good lab data does not necessarily mean good real-user experiences, is stated in About PageSpeed Insights, with field-data eligibility covered in the CrUX methodology. The INP definition, thresholds and lab caveat are on web.dev, and its promotion to a Core Web Vital on 12 March 2024 is here. The navigation share and the eligibility blockers are from back/forward cache. The fixing order is mine. If you have a page holding 100 in the lab and failing Core Web Vitals in the field, I would like to know which metric broke first — my guess is INP nearly every time, but I would rather have other people's data than my guess.