Interaction invoker types
What kind of handler blocked the interaction: event listener, timer, promise reaction.
At a glance the headline numbers for Interaction invoker types
What kind of handler blocked the interaction: event listener, timer, promise reaction.
Event-listener callbacks carry 36.1% of the blocking work behind slow interactions.
The interaction invoker types mix who uses what, and how stable each group is
Interaction invoker types. On the fleet: 36.1% event-listener, 34.0% classic-script, 27.3% user-callback.
By count event-listener leads (36.1%); by bytes it is classic-script (0.0%). computed
Passing CLS per bucket every category and count level at once - color is the pass rate
Each row is a category, each column its own count bucket (few on the left, many on the right); the cell is the share of those sites passing CLS.
No category moves the CLS pass rate much, however many a site ships. computed
Few vs many - does quantity cost CLS? the pass rate with few vs many of each category
Per category: the pass rate among pages with FEW of it (hollow ring) against pages with MANY (solid dot), worst trend first. Thin buckets are excluded from the endpoints.
More Module-script costs the most: the CLS pass rate falls from 77% with few to 73% with many. computed
Why this matters for the Core Web Vitals, and where to start fixing it
When an interaction lags, some piece of JavaScript held the main thread. This metric names the kind. An event listener means the click handler itself did too much. A timer means scheduled work got in the way, often a third-party script polling on setTimeout. A promise reaction means async work came back and ran in one long chunk.
The kind points at the owner. Slow event listeners are your code and your framework. Timer churn is usually the tag pile. Promise reactions are awaited work that needed breaking up. Identify the kind first, because the fix differs per kind.
Chrome field data from 189,915 sites, representing millions of real page loads. How we measured.
Live queries (2) — admin only
SELECT 1 AS ok FROM site_metric_bags LIMIT 0;
WITH flat AS (
SELECT b.cat, b.n, b.size, s.crux."phone".cls AS cwv_val
FROM site_metric_bags b
JOIN sites s ON s.origin = b.origin
WHERE b.path = 'inp.invoker_types'
AND b.cat IS NOT NULL
),
totals AS (
SELECT cat,
SUM(n) AS fleet_n,
SUM(size) AS fleet_size,
COUNT(*) FILTER (WHERE n IS NOT NULL) AS sample,
COUNT(*) FILTER (WHERE n > 0) AS with_any,
quantile_disc(n, 0.95) AS p95,
COUNT(*) AS n_rows
FROM flat
GROUP BY cat
HAVING COUNT(*) >= (SELECT COUNT(DISTINCT origin) FROM site_metric_bags WHERE path = 'inp.invoker_types') * 0.005
),
widths AS (
SELECT *,
GREATEST(1, CAST(round(COALESCE(p95, 0)) AS INTEGER)) AS cap,
LEAST(GREATEST(1, CAST(round(COALESCE(p95, 0)) AS INTEGER)), 12 - 1) AS regular_buckets
FROM totals
),
widths2 AS (
SELECT *,
GREATEST(1, CAST(ceil(cap * 1.0 / regular_buckets) AS INTEGER)) AS width
FROM widths
),
binned AS (
SELECT f.cat, f.cwv_val, w.fleet_n, w.fleet_size, w.sample, w.with_any, w.width, w.regular_buckets,
CASE WHEN f.n IS NULL THEN NULL
ELSE LEAST(CAST(FLOOR(f.n * 1.0 / w.width) AS INTEGER), w.regular_buckets)
END AS bucket_idx
FROM flat f
JOIN widths2 w ON f.cat = w.cat
)
SELECT cat, fleet_n, fleet_size, sample, with_any, width, regular_buckets,
bucket_idx,
COUNT(*) AS n,
quantile_disc(cwv_val, 0.5) AS median,
COUNT(*) FILTER (WHERE cwv_val IS NOT NULL) AS total_cwv,
COUNT(*) FILTER (WHERE cwv_val IS NOT NULL AND cwv_val <= 0.1) AS good
FROM binned
WHERE bucket_idx IS NOT NULL
GROUP BY cat, fleet_n, fleet_size, sample, with_any, width, regular_buckets, bucket_idx
ORDER BY cat, bucket_idx;