Scripts per page

How many scripts the page runs and their over-the-wire weight.

Field data PhoneDesktopAll Scope All sites Q2 2026 edition · Desktop field outcomes
Metric LCP INP CLS
1

At a glance the headline numbers for Scripts per page

How many scripts the page runs and their over-the-wire weight.

26
script count
on the typical page
552 KB
script weight
on the typical page
1,007 KB
1 in 4 pages exceed this
script weight
180,899
sites measured
desktop field data

The typical page runs 26 scripts weighing 552 KB.

The State of Web Vitals · Q2 2026 · 189,915 sites · desktop field datacorewebvitals.io/state-of-cwv
2

Scripts per page — n the value at each percentile across all sites

5
p10
13
p25
26
p50
49
p75
79
p90
156
p99

Scripts per page — n 26. p75 49. p99 156. computed

The State of Web Vitals · Q2 2026 · 189,915 sites · desktop field datacorewebvitals.io/state-of-cwv
3

Scripts per page — size the value at each percentile across all sites

111 KB
p10
251 KB
p25
552 KB
p50
1,007 KB
p75
1.6 MB
p90
3.7 MB
p99

Scripts per page — size 552 KB. p75 1,007 KB. p99 3.7 MB. computed

The State of Web Vitals · Q2 2026 · 189,915 sites · desktop field datacorewebvitals.io/state-of-cwv
4

Why this matters for the Core Web Vitals, and where to start fixing it

Script weight is the most expensive weight. A kilobyte of JavaScript costs more than a kilobyte of image, because after the download it is parsed, compiled and executed on the main thread. That is the same thread that must answer every click and keystroke, which is why script totals track INP.

The count matters next to the bytes: every script is a potential long task and another spot for the main thread to stall. Most pages would lose nothing by deferring most of their scripts. The ones that truly must run early are rare.

Related signals DOM size → Page weight & requests → Image source mix → Stylesheet loading mix → Chrome field data from 189,915 sites, representing millions of real page loads · How we measured
Live queries (4) — admin only
Query #1: 162.9 ms
SELECT COUNT(*) AS count,
            quantile_disc(m.scripts.total.n, 0.10) AS p10,
            quantile_disc(m.scripts.total.n, 0.25) AS p25,
            quantile_disc(m.scripts.total.n, 0.50) AS p50,
            quantile_disc(m.scripts.total.n, 0.75) AS p75,
            quantile_disc(m.scripts.total.n, 0.90) AS p90,
            quantile_disc(m.scripts.total.n, 0.99) AS p99
            FROM sites WHERE m.scripts.total.n IS NOT NULL;
Query #2: 11.8 ms
SELECT CASE WHEN m.scripts.total.n >= 5 AND m.scripts.total.n < 10 THEN 0 WHEN m.scripts.total.n >= 10 AND m.scripts.total.n < 15 THEN 1 WHEN m.scripts.total.n >= 15 AND m.scripts.total.n < 20 THEN 2 WHEN m.scripts.total.n >= 20 AND m.scripts.total.n < 25 THEN 3 WHEN m.scripts.total.n >= 25 AND m.scripts.total.n < 30 THEN 4 WHEN m.scripts.total.n >= 30 AND m.scripts.total.n < 35 THEN 5 WHEN m.scripts.total.n >= 35 AND m.scripts.total.n < 40 THEN 6 WHEN m.scripts.total.n >= 40 AND m.scripts.total.n < 45 THEN 7 WHEN m.scripts.total.n >= 45 AND m.scripts.total.n < 50 THEN 8 WHEN m.scripts.total.n >= 50 AND m.scripts.total.n < 55 THEN 9 WHEN m.scripts.total.n >= 55 AND m.scripts.total.n < 60 THEN 10 WHEN m.scripts.total.n >= 60 AND m.scripts.total.n < 65 THEN 11 WHEN m.scripts.total.n >= 65 AND m.scripts.total.n < 70 THEN 12 WHEN m.scripts.total.n >= 70 AND m.scripts.total.n < 75 THEN 13 WHEN m.scripts.total.n >= 75 AND m.scripts.total.n < 80 THEN 14 WHEN m.scripts.total.n >= 80 THEN 15 END AS bucket_idx, COUNT(*) AS n,
            quantile_disc(crux."desktop".cls, 0.5) AS median,
            COUNT(*) FILTER (WHERE crux."desktop".cls IS NOT NULL AND crux."desktop".cls <= 0.1) * 1.0 / NULLIF(COUNT(*) FILTER (WHERE crux."desktop".cls IS NOT NULL), 0) AS good_pct
            FROM sites WHERE m.scripts.total.n IS NOT NULL GROUP BY bucket_idx;
Query #3: 195.0 ms
SELECT COUNT(*) AS count,
            quantile_disc(m.scripts.total.size, 0.10) AS p10,
            quantile_disc(m.scripts.total.size, 0.25) AS p25,
            quantile_disc(m.scripts.total.size, 0.50) AS p50,
            quantile_disc(m.scripts.total.size, 0.75) AS p75,
            quantile_disc(m.scripts.total.size, 0.90) AS p90,
            quantile_disc(m.scripts.total.size, 0.99) AS p99
            FROM sites WHERE m.scripts.total.size IS NOT NULL;
Query #4: 12.6 ms
SELECT CASE WHEN m.scripts.total.size >= 0 AND m.scripts.total.size < 200 THEN 0 WHEN m.scripts.total.size >= 200 AND m.scripts.total.size < 400 THEN 1 WHEN m.scripts.total.size >= 400 AND m.scripts.total.size < 600 THEN 2 WHEN m.scripts.total.size >= 600 AND m.scripts.total.size < 800 THEN 3 WHEN m.scripts.total.size >= 800 AND m.scripts.total.size < 1000 THEN 4 WHEN m.scripts.total.size >= 1000 AND m.scripts.total.size < 1200 THEN 5 WHEN m.scripts.total.size >= 1200 AND m.scripts.total.size < 1400 THEN 6 WHEN m.scripts.total.size >= 1400 AND m.scripts.total.size < 1600 THEN 7 WHEN m.scripts.total.size >= 1600 AND m.scripts.total.size < 1800 THEN 8 WHEN m.scripts.total.size >= 1800 THEN 9 END AS bucket_idx, COUNT(*) AS n,
            quantile_disc(crux."desktop".cls, 0.5) AS median,
            COUNT(*) FILTER (WHERE crux."desktop".cls IS NOT NULL AND crux."desktop".cls <= 0.1) * 1.0 / NULLIF(COUNT(*) FILTER (WHERE crux."desktop".cls IS NOT NULL), 0) AS good_pct
            FROM sites WHERE m.scripts.total.size IS NOT NULL GROUP BY bucket_idx;
JSON file lookups (4)
20260625/meta.json 0.03 ms
20260625/types.json 0.47 ms
20260625/loaf-scripts.json 0.30 ms
20260625/menu.json 0.14 ms