CLS distribution
How CLS is distributed across real-user data, plus pass-rate breakdown.
At a glance the headline numbers for CLS distribution
How CLS is distributed across real-user data, plus pass-rate breakdown.
88.8% of sites pass CLS. The typical site's CLS is 0.00. The worst 10% are above 0.12.
The CLS distribution site count at each CLS, from good to poor
The tallest bar is between 0 and 0.02. 74% of sites are in that one range, 0.08 under Google's 0.1 limit. Half of all sites report a CLS of 0. The tail is long. The worst 10% are above 0.12 and the worst 1% above 0.73.
The CLS pass rate the share of sites that are good, needs improvement and poor
88.8% of sites pass CLS. 6.4% are in the needs improvement band, between 0.1 and 0.25. 4.8% are poor, above 0.25. Misses split about evenly between the two.
Why this matters for the Core Web Vitals, and where to start fixing it
Cumulative Layout Shift measures how much the page moves around while it loads. A button jumps just as someone goes to tap it, an ad pushes the article down, the text reflows when a late font arrives. Every one of those is a layout shift, and they add up into a score that reflects how stable the page feels. Unlike the other vitals, CLS is rarely about speed and almost always about reserving space.
Start by giving everything that loads late a place to land. Set width and height on images and video so the browser reserves the box before the file arrives. Reserve space for ads, embeds and banners instead of letting them push content. Load fonts so the fallback and the web font take the same room, and keep animations on transform rather than properties that trigger layout.
How are sites doing on CLS?
88.8% of sites have a good CLS. The typical site sits at 0.02 at the 75th percentile; the worst 1% reach 0.73.
Chrome field data from 189,915 sites, representing millions of real page loads. How we measured.
Live queries (2) — admin only
SELECT COUNT(*) AS count,
COUNT(*) FILTER (WHERE crux."phone".cls <= 0.1) * 1.0 / COUNT(*) AS good,
COUNT(*) FILTER (WHERE crux."phone".cls > 0.1 AND crux."phone".cls <= 0.25) * 1.0 / COUNT(*) AS needs_improvement,
COUNT(*) FILTER (WHERE crux."phone".cls > 0.25) * 1.0 / COUNT(*) AS poor,
quantile_disc(crux."phone".cls, 0.10) AS p10,
quantile_disc(crux."phone".cls, 0.25) AS p25,
quantile_disc(crux."phone".cls, 0.50) AS p50,
quantile_disc(crux."phone".cls, 0.75) AS p75,
quantile_disc(crux."phone".cls, 0.90) AS p90,
quantile_disc(crux."phone".cls, 0.99) AS p99
FROM sites WHERE 1=1 AND crux."phone".cls IS NOT NULL;
SELECT CASE WHEN crux."phone".cls >= 0 AND crux."phone".cls < 0.02 THEN 0 WHEN crux."phone".cls >= 0.02 AND crux."phone".cls < 0.04 THEN 1 WHEN crux."phone".cls >= 0.04 AND crux."phone".cls < 0.06 THEN 2 WHEN crux."phone".cls >= 0.06 AND crux."phone".cls < 0.08 THEN 3 WHEN crux."phone".cls >= 0.08 AND crux."phone".cls < 0.1 THEN 4 WHEN crux."phone".cls >= 0.1 AND crux."phone".cls < 0.12 THEN 5 WHEN crux."phone".cls >= 0.12 AND crux."phone".cls < 0.14 THEN 6 WHEN crux."phone".cls >= 0.14 AND crux."phone".cls < 0.16 THEN 7 WHEN crux."phone".cls >= 0.16 AND crux."phone".cls < 0.18 THEN 8 WHEN crux."phone".cls >= 0.18 AND crux."phone".cls < 0.2 THEN 9 WHEN crux."phone".cls >= 0.2 AND crux."phone".cls < 0.22 THEN 10 WHEN crux."phone".cls >= 0.22 AND crux."phone".cls < 0.24 THEN 11 WHEN crux."phone".cls >= 0.24 AND crux."phone".cls < 0.26 THEN 12 WHEN crux."phone".cls >= 0.26 AND crux."phone".cls < 0.28 THEN 13 WHEN crux."phone".cls >= 0.28 AND crux."phone".cls < 0.3 THEN 14 WHEN crux."phone".cls >= 0.3 AND crux."phone".cls < 0.32 THEN 15 WHEN crux."phone".cls >= 0.32 AND crux."phone".cls < 0.34 THEN 16 WHEN crux."phone".cls >= 0.34 AND crux."phone".cls < 0.36 THEN 17 WHEN crux."phone".cls >= 0.36 AND crux."phone".cls < 0.38 THEN 18 WHEN crux."phone".cls >= 0.38 AND crux."phone".cls < 0.4 THEN 19 WHEN crux."phone".cls >= 0.4 THEN 20 END AS bucket_idx, COUNT(*) AS count FROM sites WHERE 1=1 AND crux."phone".cls IS NOT NULL GROUP BY bucket_idx;