Script coverage (used vs unused)
Of the JavaScript shipped, how much actually ran during load (used vs unused bytes, Chrome coverage).
At a glance the headline numbers for Script coverage (used vs unused)
Of the JavaScript shipped, how much actually ran during load (used vs unused bytes, Chrome coverage).
866 KB of JavaScript on the typical page never ran during load.
Where the milliseconds go the phases at the median, against the budget
At the median the whole stack uses 1.9s - already past the 200ms INP budget. The biggest piece is Used kb at 1.0s, 54% of the total. computed
Passing LCP per phase the share of sites passing, by how long each phase takes
Each line is one phase: left = sites where it is quick, right = sites where it drags (buckets, short to long). The steeper the fall, the more that phase decides LCP.
Used kb falls hardest: from its fastest to its slowest bucket the LCP pass rate drops 18 points, down to 72%. computed
The 2 distributions how each phase spreads across sites - color is the share passing in that range
Used kb stays green across its whole range: it never decides LCP. Used kb turns red in its tail - the failing sites live there. computed
Why this matters for the Core Web Vitals, and where to start fixing it
Chrome's coverage data splits the JavaScript you ship into bytes that ran during load and bytes that did not. The unused half still cost the full price: downloaded, parsed and compiled on the main thread, all before doing nothing.
Unused JavaScript is usually whole features shipped everywhere: the checkout bundle on the blog, admin widgets for anonymous visitors. Code splitting per route is the structural fix. Deleting dead dependencies is the cheap one.
Chrome field data from 189,915 sites, representing millions of real page loads. How we measured.
Live queries (4) — admin only
SELECT COUNT(*) AS count,
quantile_disc(m.scripts.coverage.used_kb, 0.10) AS p10,
quantile_disc(m.scripts.coverage.used_kb, 0.25) AS p25,
quantile_disc(m.scripts.coverage.used_kb, 0.50) AS p50,
quantile_disc(m.scripts.coverage.used_kb, 0.75) AS p75,
quantile_disc(m.scripts.coverage.used_kb, 0.90) AS p90,
quantile_disc(m.scripts.coverage.used_kb, 0.99) AS p99
FROM sites WHERE m.scripts.coverage.used_kb IS NOT NULL;
SELECT CASE WHEN m.scripts.coverage.used_kb >= 0 AND m.scripts.coverage.used_kb < 500 THEN 0 WHEN m.scripts.coverage.used_kb >= 500 AND m.scripts.coverage.used_kb < 1000 THEN 1 WHEN m.scripts.coverage.used_kb >= 1000 AND m.scripts.coverage.used_kb < 1500 THEN 2 WHEN m.scripts.coverage.used_kb >= 1500 AND m.scripts.coverage.used_kb < 2000 THEN 3 WHEN m.scripts.coverage.used_kb >= 2000 AND m.scripts.coverage.used_kb < 2500 THEN 4 WHEN m.scripts.coverage.used_kb >= 2500 AND m.scripts.coverage.used_kb < 3000 THEN 5 WHEN m.scripts.coverage.used_kb >= 3000 THEN 6 END AS bucket_idx, COUNT(*) AS n,
quantile_disc(crux."phone".lcp, 0.5) AS median,
COUNT(*) FILTER (WHERE crux."phone".lcp IS NOT NULL AND crux."phone".lcp <= 2500) * 1.0 / NULLIF(COUNT(*) FILTER (WHERE crux."phone".lcp IS NOT NULL), 0) AS good_pct
FROM sites WHERE m.scripts.coverage.used_kb IS NOT NULL GROUP BY bucket_idx;
SELECT COUNT(*) AS count,
quantile_disc(m.scripts.coverage.unused_kb, 0.10) AS p10,
quantile_disc(m.scripts.coverage.unused_kb, 0.25) AS p25,
quantile_disc(m.scripts.coverage.unused_kb, 0.50) AS p50,
quantile_disc(m.scripts.coverage.unused_kb, 0.75) AS p75,
quantile_disc(m.scripts.coverage.unused_kb, 0.90) AS p90,
quantile_disc(m.scripts.coverage.unused_kb, 0.99) AS p99
FROM sites WHERE m.scripts.coverage.unused_kb IS NOT NULL;
SELECT CASE WHEN m.scripts.coverage.unused_kb >= 0 AND m.scripts.coverage.unused_kb < 500 THEN 0 WHEN m.scripts.coverage.unused_kb >= 500 AND m.scripts.coverage.unused_kb < 1000 THEN 1 WHEN m.scripts.coverage.unused_kb >= 1000 AND m.scripts.coverage.unused_kb < 1500 THEN 2 WHEN m.scripts.coverage.unused_kb >= 1500 AND m.scripts.coverage.unused_kb < 2000 THEN 3 WHEN m.scripts.coverage.unused_kb >= 2000 AND m.scripts.coverage.unused_kb < 2500 THEN 4 WHEN m.scripts.coverage.unused_kb >= 2500 THEN 5 END AS bucket_idx, COUNT(*) AS n,
quantile_disc(crux."phone".lcp, 0.5) AS median,
COUNT(*) FILTER (WHERE crux."phone".lcp IS NOT NULL AND crux."phone".lcp <= 2500) * 1.0 / NULLIF(COUNT(*) FILTER (WHERE crux."phone".lcp IS NOT NULL), 0) AS good_pct
FROM sites WHERE m.scripts.coverage.unused_kb IS NOT NULL GROUP BY bucket_idx;