How fast it is, measured, not felt.
A real browser loads your pages the way a visitor's does and writes down every request it made. One page on the free scan, up to 20 on a paid plan, with Core Web Vitals taken from the page itself rather than a lab profile.
Every request, attributed.
Headers tell you what a server promises. A browser tells you what your application actually does: which requests it makes, in what order, how many bytes they carry and who they go to.
- Cold, then navigated
Each route is loaded cold and then reached again through client navigation - 3 in-app links per page - so a refetch the framework should have cached shows up as one.
- Routes, clustered
Pages that are the same template with different data are grouped, so a hundred product pages are one route with one baseline.
- Holding pages waited out
A host that serves a self-reloading placeholder is given up to 9 seconds to hand over the real page before anything is judged.
- Recorded, not screenshotted
What is kept is the request log, the timings and the console - never a picture of the page.
- /document · 41 KB
- /_next/static/chunks/main.jsscript · 312 KB
- cdn.segment.com/analytics.jsscript · 188 KB
- /api/orders?status=openfetch · 148 KB
- /api/orders/1041fetch · 6 KB
- /api/orders/1042fetch · 6 KB
- /api/orders/1043 … ×12fetch · 6 KB
- images.unsplash.com/hero.jpgimage · 1,420 KB
17 rules, each with a number on it.
A threshold is printed beside every rule, because a finding that says “slow” without saying what would have been fast enough is an opinion.
Measured on the real load, judged at Google's own boundaries, then poor at 4 s, 0.25 and 500 ms.
A page that takes longer than this to settle is reported with its timings.
A list request followed by one call per item to the same :id route; high at 30.
That many xhr or fetch calls, or that many requests of any kind, during one page load.
The same method and URL fetched three times in one load; medium at six.
API calls that waited for each other when they could have run at once; high at five deep.
Bytes from other origins, as a share of the page and as an absolute size; medium at 60% and 1.5 MB.
Synchronous external scripts in the head, each of which delays the first paint.
Static files served without a cache lifetime of at least a day.
Downloaded pixels against the pixels actually shown; medium when a megabyte is wasted.
Total transferred bytes for one page load.
One page load that exchanges that many frames, or reopens the same socket that often.
Requests the page made to its own origin that came back 4xx or 5xx.
“Slower than before” becomes a measurement.
Load, DOM-ready and time to first byte are remembered per route. A regression is raised when a load is at least 1.5× the baseline of the last 8 samples and slower than 1,500 ms in absolute terms, so a page that went from fast to slightly less fast is not an alarm.
What breaks in the open.
A page that renders blank, a chunk that never loads, a script that comes back as HTML: the failures a visitor sees and an uptime check does not.
- JavaScript errors on loadbrowser.reliability.javascript-errors
- Requests that fail in productionbrowser.reliability.failed-requests
- WebSocket reconnect loopbrowser.reliability.websocket-reconnect-loop
- Script chunk failed to load (deploy mismatch)browser.reliability.chunk-load-failure
- Script served as an HTML pagebrowser.reliability.script-served-as-html
- The 404 page itself is brokenbrowser.reliability.error-page-broken-resources
One page free. Twenty with a plan.
- One real Chromium load of the page you gave it, plus a visit to a page that does not exist.
- Core Web Vitals, page weight, third-party share, render-blocking scripts and oversized images from that one load.
- No crawl, no client-navigation pass, no burst against a rate limit.
- Up to 20 pages per scan, routes clustered, each with a baseline.
- The client-navigation pass, and a bounded burst of 12 requests to see whether a limit exists - only once you have verified the domain.
- Live-site scans are free and unlimited; the queue and a five-minute cooldown are the only brake.
Measure it on your app.
A URL, an email, one real browser load. The report says which request made the page slow, and what to do about it.