Skip to content

Commit b817cb4

Browse files
dwsmarttunetheweb
andauthored
Page weight sql queries 2025 (#4143)
* bytes_per_type.sql changed from .all to .crawl * inital commit of 2025 queries * Correct to July 2025 data * LCP in seconds * capture full range * all to crawl * remove fid * add good percentage of cwv * don't split home / internal * small linting fix * facades usage query rewritten to match missing v2 from 2024 * correct facades query * Update sql/2025/page-weight/crux_cwv_trend.sql simplify JSON access Co-authored-by: Barry Pollard <barrypollard@google.com> * remove " -- Adjust this date as needed" comment * Cleanup JSON value, and remove uneeded EXTRACT * cleanup JSON field access * remove extract as not needed * use JSON columns * typo fix * comment to show this is URL level data * fix typo * use SAFE_CAST --------- Co-authored-by: Barry Pollard <barrypollard@google.com>
1 parent 7b678ee commit b817cb4

14 files changed

Lines changed: 518 additions & 0 deletions
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
SELECT
2+
percentile,
3+
client,
4+
is_root_page,
5+
APPROX_QUANTILES(CAST(JSON_VALUE(summary.bytesTotal) AS INT64) / 1024, 1000)[OFFSET(percentile * 10)] AS total_kbytes,
6+
APPROX_QUANTILES(CAST(JSON_VALUE(summary.bytesHtml) AS INT64) / 1024, 1000)[OFFSET(percentile * 10)] AS html_kbytes,
7+
APPROX_QUANTILES(CAST(JSON_VALUE(summary.bytesJS) AS INT64) / 1024, 1000)[OFFSET(percentile * 10)] AS js_kbytes,
8+
APPROX_QUANTILES(CAST(JSON_VALUE(summary.bytesCss) AS INT64) / 1024, 1000)[OFFSET(percentile * 10)] AS css_kbytes,
9+
APPROX_QUANTILES(CAST(JSON_VALUE(summary.bytesImg) AS INT64) / 1024, 1000)[OFFSET(percentile * 10)] AS img_kbytes,
10+
APPROX_QUANTILES(CAST(JSON_VALUE(summary.bytesOther) AS INT64) / 1024, 1000)[OFFSET(percentile * 10)] AS other_kbytes,
11+
APPROX_QUANTILES(CAST(JSON_VALUE(summary.bytesHtmlDoc) AS INT64) / 1024, 1000)[OFFSET(percentile * 10)] AS html_doc_kbytes,
12+
APPROX_QUANTILES(CAST(JSON_VALUE(summary.bytesFont) AS INT64) / 1024, 1000)[OFFSET(percentile * 10)] AS font_kbytes
13+
FROM
14+
`httparchive.crawl.pages`,
15+
UNNEST([10, 25, 50, 75, 90, 100]) AS percentile
16+
WHERE
17+
date = '2025-07-01'
18+
GROUP BY
19+
percentile,
20+
client,
21+
is_root_page
22+
ORDER BY
23+
client,
24+
is_root_page,
25+
percentile
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
SELECT
2+
client,
3+
is_root_page,
4+
COUNTIF(JSON_VALUE(lighthouse['audits.uses-text-compression'].score) IS NULL) AS null_count,
5+
COUNTIF(SAFE_CAST(JSON_VALUE(lighthouse['audits.uses-text-compression'].score) AS FLOAT64) >= 0.9) AS pass_count,
6+
COUNTIF(SAFE_CAST(JSON_VALUE(lighthouse['audits.uses-text-compression'].score) AS FLOAT64) < 0.9) AS fail_count,
7+
COUNT(0) AS total,
8+
COUNTIF(SAFE_CAST(JSON_VALUE(lighthouse['audits.uses-text-compression'].score) AS FLOAT64) >= 0.9) / COUNT(0) AS pct_pass,
9+
COUNTIF(SAFE_CAST(JSON_VALUE(lighthouse['audits.uses-text-compression'].score) AS FLOAT64) < 0.9) / COUNT(0) AS pct_fail
10+
FROM
11+
`httparchive.crawl.pages`
12+
WHERE
13+
date = '2025-07-01'
14+
GROUP BY
15+
client,
16+
is_root_page
17+
ORDER BY
18+
client,
19+
is_root_page,
20+
null_count,
21+
pass_count,
22+
fail_count
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
WITH metrics_data AS (
2+
SELECT
3+
date,
4+
client,
5+
CAST(JSON_VALUE(summary.bytesTotal) AS INT64) AS bytes_total,
6+
-- these are page level CrUX metrics, pages may not have all / any metrics available, but do represent the user experience of the measured page weight vs. origin.
7+
CAST(JSON_VALUE(summary.crux.metrics.largest_contentful_paint.percentiles.p75) AS FLOAT64) AS lcp,
8+
CAST(JSON_VALUE(summary.crux.metrics.cumulative_layout_shift.percentiles.p75) AS FLOAT64) AS cls,
9+
CAST(JSON_VALUE(summary.crux.metrics.interaction_to_next_paint.percentiles.p75) AS FLOAT64) AS inp,
10+
CAST(JSON_VALUE(summary.crux.metrics.first_contentful_paint.percentiles.p75) AS FLOAT64) AS fcp,
11+
CAST(JSON_VALUE(summary.crux.metrics.experimental_time_to_first_byte.percentiles.p75) AS FLOAT64) AS ttfb
12+
FROM
13+
`httparchive.crawl.pages`
14+
WHERE
15+
date >= '2024-07-01' AND
16+
date <= '2025-07-01'
17+
)
18+
19+
SELECT
20+
date,
21+
client,
22+
COUNT(DISTINCT IF(bytes_total > 0, bytes_total, NULL)) AS total_pages,
23+
24+
-- Page Size metrics
25+
ROUND(APPROX_QUANTILES(bytes_total, 1000)[OFFSET(100)] / 1024, 2) AS p10_page_size_kb,
26+
ROUND(APPROX_QUANTILES(bytes_total, 1000)[OFFSET(250)] / 1024, 2) AS p25_page_size_kb,
27+
ROUND(APPROX_QUANTILES(bytes_total, 1000)[OFFSET(500)] / 1024, 2) AS p50_page_size_kb,
28+
ROUND(APPROX_QUANTILES(bytes_total, 1000)[OFFSET(750)] / 1024, 2) AS p75_page_size_kb,
29+
ROUND(APPROX_QUANTILES(bytes_total, 1000)[OFFSET(900)] / 1024, 2) AS p90_page_size_kb,
30+
31+
-- LCP metrics
32+
ROUND(APPROX_QUANTILES(lcp, 1000)[OFFSET(100)], 2) AS p10_lcp,
33+
ROUND(APPROX_QUANTILES(lcp, 1000)[OFFSET(250)], 2) AS p25_lcp,
34+
ROUND(APPROX_QUANTILES(lcp, 1000)[OFFSET(500)], 2) AS p50_lcp,
35+
ROUND(APPROX_QUANTILES(lcp, 1000)[OFFSET(750)], 2) AS p75_lcp,
36+
ROUND(APPROX_QUANTILES(lcp, 1000)[OFFSET(900)], 2) AS p90_lcp,
37+
38+
-- CLS metrics
39+
ROUND(APPROX_QUANTILES(cls, 1000)[OFFSET(100)], 3) AS p10_cls,
40+
ROUND(APPROX_QUANTILES(cls, 1000)[OFFSET(250)], 3) AS p25_cls,
41+
ROUND(APPROX_QUANTILES(cls, 1000)[OFFSET(500)], 3) AS p50_cls,
42+
ROUND(APPROX_QUANTILES(cls, 1000)[OFFSET(750)], 3) AS p75_cls,
43+
ROUND(APPROX_QUANTILES(cls, 1000)[OFFSET(900)], 3) AS p90_cls,
44+
45+
-- INP metrics
46+
ROUND(APPROX_QUANTILES(inp, 1000)[OFFSET(100)], 2) AS p10_inp,
47+
ROUND(APPROX_QUANTILES(inp, 1000)[OFFSET(250)], 2) AS p25_inp,
48+
ROUND(APPROX_QUANTILES(inp, 1000)[OFFSET(500)], 2) AS p50_inp,
49+
ROUND(APPROX_QUANTILES(inp, 1000)[OFFSET(750)], 2) AS p75_inp,
50+
ROUND(APPROX_QUANTILES(inp, 1000)[OFFSET(900)], 2) AS p90_inp,
51+
52+
-- FCP metrics
53+
ROUND(APPROX_QUANTILES(fcp, 1000)[OFFSET(100)], 2) AS p10_fcp,
54+
ROUND(APPROX_QUANTILES(fcp, 1000)[OFFSET(250)], 2) AS p25_fcp,
55+
ROUND(APPROX_QUANTILES(fcp, 1000)[OFFSET(500)], 2) AS p50_fcp,
56+
ROUND(APPROX_QUANTILES(fcp, 1000)[OFFSET(750)], 2) AS p75_fcp,
57+
ROUND(APPROX_QUANTILES(fcp, 1000)[OFFSET(900)], 2) AS p90_fcp,
58+
59+
-- TTFB metrics
60+
ROUND(APPROX_QUANTILES(ttfb, 1000)[OFFSET(100)], 2) AS p10_ttfb,
61+
ROUND(APPROX_QUANTILES(ttfb, 1000)[OFFSET(250)], 2) AS p25_ttfb,
62+
ROUND(APPROX_QUANTILES(ttfb, 1000)[OFFSET(500)], 2) AS p50_ttfb,
63+
ROUND(APPROX_QUANTILES(ttfb, 1000)[OFFSET(750)], 2) AS p75_ttfb,
64+
ROUND(APPROX_QUANTILES(ttfb, 1000)[OFFSET(900)], 2) AS p90_ttfb,
65+
66+
-- Good CWV percentages
67+
ROUND(COUNTIF(lcp <= 2500) / COUNT(0) * 100, 2) AS good_lcp_percent,
68+
ROUND(COUNTIF(cls <= 0.1) / COUNT(0) * 100, 2) AS good_cls_percent,
69+
ROUND(COUNTIF(inp <= 200) / COUNT(0) * 100, 2) AS good_inp_percent,
70+
ROUND(COUNTIF(fcp <= 1800) / COUNT(0) * 100, 2) AS good_fcp_percent,
71+
ROUND(COUNTIF(ttfb <= 800) / COUNT(0) * 100, 2) AS good_ttfb_percent
72+
73+
FROM
74+
metrics_data
75+
GROUP BY
76+
date,
77+
client
78+
ORDER BY
79+
date DESC,
80+
client

sql/2025/page-weight/cwv_by_mb.sql

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
WITH metrics_data AS (
2+
SELECT
3+
date,
4+
client,
5+
is_root_page,
6+
CAST(JSON_VALUE(summary.bytesTotal) AS INT64) AS bytes_total,
7+
CAST(JSON_VALUE(summary.crux.metrics.largest_contentful_paint.percentiles.p75) AS FLOAT64) AS lcp,
8+
CAST(JSON_VALUE(summary.crux.metrics.cumulative_layout_shift.percentiles.p75) AS FLOAT64) AS cls,
9+
CAST(JSON_VALUE(summary.crux.metrics.interaction_to_next_paint.percentiles.p75) AS FLOAT64) AS inp,
10+
CAST(JSON_VALUE(summary.crux.metrics.first_contentful_paint.percentiles.p75) AS FLOAT64) AS fcp,
11+
CAST(JSON_VALUE(summary.crux.metrics.experimental_time_to_first_byte.percentiles.p75) AS FLOAT64) AS ttfb
12+
FROM
13+
`httparchive.crawl.pages`
14+
WHERE
15+
date = '2025-07-01'
16+
)
17+
18+
SELECT
19+
client,
20+
is_root_page,
21+
-- LCP metrics
22+
-- 1mb and below
23+
ROUND(APPROX_QUANTILES(IF(bytes_total <= 1048576, lcp, NULL), 1000)[OFFSET(750)] / 1000, 2) AS p75_lcp_1mb_and_below,
24+
-- 1mb to 2mb
25+
ROUND(APPROX_QUANTILES(IF(bytes_total > 1048576 AND bytes_total <= 2097152, lcp, NULL), 1000)[OFFSET(750)] / 1000, 2) AS p75_lcp_1mb_to_2mb,
26+
-- 2mb to 3mb
27+
ROUND(APPROX_QUANTILES(IF(bytes_total > 2097152 AND bytes_total <= 3145728, lcp, NULL), 1000)[OFFSET(750)] / 1000, 2) AS p75_lcp_2mb_to_3mb,
28+
-- 3mb to 4mb
29+
ROUND(APPROX_QUANTILES(IF(bytes_total > 3145728 AND bytes_total <= 4194304, lcp, NULL), 1000)[OFFSET(750)] / 1000, 2) AS p75_lcp_3mb_to_4mb,
30+
-- 4mb and 5mb
31+
ROUND(APPROX_QUANTILES(IF(bytes_total > 4194304 AND bytes_total <= 5242880, lcp, NULL), 1000)[OFFSET(750)] / 1000, 2) AS p75_lcp_4mb_to_5mb,
32+
-- 5mb and above
33+
ROUND(APPROX_QUANTILES(IF(bytes_total >= 5242880, lcp, NULL), 1000)[OFFSET(750)] / 1000, 2) AS p75_lcp_5mb_and_above,
34+
35+
-- CLS metrics
36+
-- 1mb and below
37+
ROUND(APPROX_QUANTILES(IF(bytes_total <= 1048576, cls, NULL), 1000)[OFFSET(750)], 2) AS p75_cls_1mb_and_below,
38+
-- 1mb to 2mb
39+
ROUND(APPROX_QUANTILES(IF(bytes_total > 1048576 AND bytes_total <= 2097152, cls, NULL), 1000)[OFFSET(750)], 2) AS p75_cls_1mb_to_2mb,
40+
-- 2mb to 3mb
41+
ROUND(APPROX_QUANTILES(IF(bytes_total > 2097152 AND bytes_total <= 3145728, cls, NULL), 1000)[OFFSET(750)], 2) AS p75_cls_2mb_to_3mb,
42+
-- 3mb to 4mb
43+
ROUND(APPROX_QUANTILES(IF(bytes_total > 3145728 AND bytes_total <= 4194304, cls, NULL), 1000)[OFFSET(750)], 2) AS p75_cls_3mb_to_4mb,
44+
-- 4mb and 5mb
45+
ROUND(APPROX_QUANTILES(IF(bytes_total > 4194304 AND bytes_total <= 5242880, cls, NULL), 1000)[OFFSET(750)], 2) AS p75_cls_4mb_to_5mb,
46+
-- 5mb and above
47+
ROUND(APPROX_QUANTILES(IF(bytes_total >= 5242880, cls, NULL), 1000)[OFFSET(750)], 2) AS p75_cls_5mb_and_above,
48+
49+
-- INP metrics
50+
-- 1mb and below
51+
ROUND(APPROX_QUANTILES(IF(bytes_total <= 1048576, inp, NULL), 1000)[OFFSET(750)], 2) AS p75_inp_1mb_and_below,
52+
-- 1mb to 2mb
53+
ROUND(APPROX_QUANTILES(IF(bytes_total > 1048576 AND bytes_total <= 2097152, inp, NULL), 1000)[OFFSET(750)], 2) AS p75_inp_1mb_to_2mb,
54+
-- 2mb to 3mb
55+
ROUND(APPROX_QUANTILES(IF(bytes_total > 2097152 AND bytes_total <= 3145728, inp, NULL), 1000)[OFFSET(750)], 2) AS p75_inp_2mb_to_3mb,
56+
-- 3mb to 4mb
57+
ROUND(APPROX_QUANTILES(IF(bytes_total > 3145728 AND bytes_total <= 4194304, inp, NULL), 1000)[OFFSET(750)], 2) AS p75_inp_3mb_to_4mb,
58+
-- 4mb and 5mb
59+
ROUND(APPROX_QUANTILES(IF(bytes_total > 4194304 AND bytes_total <= 5242880, inp, NULL), 1000)[OFFSET(750)], 2) AS p75_inp_4mb_to_5mb,
60+
-- 5mb and above
61+
ROUND(APPROX_QUANTILES(IF(bytes_total >= 5242880, inp, NULL), 1000)[OFFSET(750)], 2) AS p75_inp_5mb_and_above,
62+
63+
-- FCP metrics
64+
-- 1mb and below
65+
ROUND(APPROX_QUANTILES(IF(bytes_total <= 1048576, fcp, NULL), 1000)[OFFSET(750)], 2) AS p75_fcp_1mb_and_below,
66+
-- 1mb to 2mb
67+
ROUND(APPROX_QUANTILES(IF(bytes_total > 1048576 AND bytes_total <= 2097152, fcp, NULL), 1000)[OFFSET(750)], 2) AS p75_fcp_1mb_to_2mb,
68+
-- 2mb to 3mb
69+
ROUND(APPROX_QUANTILES(IF(bytes_total > 2097152 AND bytes_total <= 3145728, fcp, NULL), 1000)[OFFSET(750)], 2) AS p75_fcp_2mb_to_3mb,
70+
-- 3mb to 4mb
71+
ROUND(APPROX_QUANTILES(IF(bytes_total > 3145728 AND bytes_total <= 4194304, fcp, NULL), 1000)[OFFSET(750)], 2) AS p75_fcp_3mb_to_4mb,
72+
-- 4mb and 5mb
73+
ROUND(APPROX_QUANTILES(IF(bytes_total > 4194304 AND bytes_total <= 5242880, fcp, NULL), 1000)[OFFSET(750)], 2) AS p75_fcp_4mb_to_5mb,
74+
-- 5mb and above
75+
ROUND(APPROX_QUANTILES(IF(bytes_total >= 5242880, fcp, NULL), 1000)[OFFSET(750)], 2) AS p75_fcp_5mb_and_above,
76+
77+
-- TTFB metrics
78+
-- 1mb and below
79+
ROUND(APPROX_QUANTILES(IF(bytes_total <= 1048576, ttfb, NULL), 1000)[OFFSET(750)], 2) AS p75_ttfb_1mb_and_below,
80+
-- 1mb to 2mb
81+
ROUND(APPROX_QUANTILES(IF(bytes_total > 1048576 AND bytes_total <= 2097152, ttfb, NULL), 1000)[OFFSET(750)], 2) AS p75_ttfb_1mb_to_2mb,
82+
-- 2mb to 3mb
83+
ROUND(APPROX_QUANTILES(IF(bytes_total > 2097152 AND bytes_total <= 3145728, ttfb, NULL), 1000)[OFFSET(750)], 2) AS p75_ttfb_2mb_to_3mb,
84+
-- 3mb to 4mb
85+
ROUND(APPROX_QUANTILES(IF(bytes_total > 3145728 AND bytes_total <= 4194304, ttfb, NULL), 1000)[OFFSET(750)], 2) AS p75_ttfb_3mb_to_4mb,
86+
-- 4mb and 5mb
87+
ROUND(APPROX_QUANTILES(IF(bytes_total > 4194304 AND bytes_total <= 5242880, ttfb, NULL), 1000)[OFFSET(750)], 2) AS p75_ttfb_4mb_to_5mb,
88+
-- 5mb and above
89+
ROUND(APPROX_QUANTILES(IF(bytes_total >= 5242880, ttfb, NULL), 1000)[OFFSET(750)], 2) AS p75_ttfb_5mb_and_above
90+
91+
FROM
92+
metrics_data
93+
GROUP BY
94+
client,
95+
is_root_page
96+
ORDER BY
97+
client
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
SELECT
2+
client,
3+
is_root_page,
4+
COUNTIF(JSON_VALUE(lighthouse.audits['third-party-facades'].score) IS NOT NULL) AS pages_with_facades_available,
5+
COUNTIF(JSON_VALUE(lighthouse.audits['third-party-facades'].scoreDisplayMode) = 'notApplicable') AS not_applicable_count,
6+
SUM(CAST(JSON_VALUE(lighthouse.audits['third-party-facades'].metricSavings.TBT) AS FLOAT64)) AS total_blocking_time_savings_ms,
7+
COUNT(0) AS total_pages,
8+
COUNTIF(JSON_VALUE(lighthouse.audits['third-party-facades'].score) IS NOT NULL) / (COUNT(0) - COUNTIF(JSON_VALUE(lighthouse.audits['third-party-facades'].scoreDisplayMode) = 'notApplicable')) AS pct_pages_with_opportunities
9+
FROM
10+
`httparchive.crawl.pages`
11+
WHERE
12+
date = '2025-07-01'
13+
GROUP BY
14+
client,
15+
is_root_page
16+
ORDER BY
17+
client,
18+
is_root_page
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
WITH metrics_data AS (
2+
SELECT
3+
date,
4+
client,
5+
CAST(JSON_VALUE(summary.bytesTotal) AS INT64) AS bytes_total,
6+
CAST(JSON_VALUE(lighthouse.audits['largest-contentful-paint'].numericValue) AS FLOAT64) AS lcp,
7+
CAST(JSON_VALUE(lighthouse.audits['cumulative-layout-shift'].numericValue) AS FLOAT64) AS cls,
8+
CAST(JSON_VALUE(lighthouse.audits['total-blocking-time'].numericValue) AS FLOAT64) AS tbt,
9+
CAST(JSON_VALUE(lighthouse.audits['first-contentful-paint'].numericValue) AS FLOAT64) AS fcp,
10+
CAST(JSON_VALUE(lighthouse.audits['interactive'].numericValue) AS FLOAT64) AS tti,
11+
CAST(JSON_VALUE(lighthouse.categories.performance.score) AS FLOAT64) AS performance_score
12+
FROM
13+
`httparchive.crawl.pages`
14+
WHERE
15+
date >= '2024-07-01' AND
16+
date <= '2025-07-01'
17+
)
18+
19+
SELECT
20+
date,
21+
client,
22+
COUNT(DISTINCT IF(bytes_total > 0, bytes_total, NULL)) AS total_pages,
23+
24+
-- Page Size metrics
25+
ROUND(APPROX_QUANTILES(bytes_total, 1000)[OFFSET(100)] / 1024, 2) AS p10_page_size_kb,
26+
ROUND(APPROX_QUANTILES(bytes_total, 1000)[OFFSET(250)] / 1024, 2) AS p25_page_size_kb,
27+
ROUND(APPROX_QUANTILES(bytes_total, 1000)[OFFSET(500)] / 1024, 2) AS p50_page_size_kb,
28+
ROUND(APPROX_QUANTILES(bytes_total, 1000)[OFFSET(750)] / 1024, 2) AS p75_page_size_kb,
29+
ROUND(APPROX_QUANTILES(bytes_total, 1000)[OFFSET(900)] / 1024, 2) AS p90_page_size_kb,
30+
31+
-- LCP metrics
32+
ROUND(APPROX_QUANTILES(lcp, 1000)[OFFSET(100)], 2) AS p10_lcp,
33+
ROUND(APPROX_QUANTILES(lcp, 1000)[OFFSET(250)], 2) AS p25_lcp,
34+
ROUND(APPROX_QUANTILES(lcp, 1000)[OFFSET(500)], 2) AS p50_lcp,
35+
ROUND(APPROX_QUANTILES(lcp, 1000)[OFFSET(750)], 2) AS p75_lcp,
36+
ROUND(APPROX_QUANTILES(lcp, 1000)[OFFSET(900)], 2) AS p90_lcp,
37+
38+
-- CLS metrics
39+
ROUND(APPROX_QUANTILES(cls, 1000)[OFFSET(100)], 3) AS p10_cls,
40+
ROUND(APPROX_QUANTILES(cls, 1000)[OFFSET(250)], 3) AS p25_cls,
41+
ROUND(APPROX_QUANTILES(cls, 1000)[OFFSET(500)], 3) AS p50_cls,
42+
ROUND(APPROX_QUANTILES(cls, 1000)[OFFSET(750)], 3) AS p75_cls,
43+
ROUND(APPROX_QUANTILES(cls, 1000)[OFFSET(900)], 3) AS p90_cls,
44+
45+
-- TBT metrics (as a proxy for FID/INP)
46+
ROUND(APPROX_QUANTILES(tbt, 1000)[OFFSET(100)], 2) AS p10_tbt,
47+
ROUND(APPROX_QUANTILES(tbt, 1000)[OFFSET(250)], 2) AS p25_tbt,
48+
ROUND(APPROX_QUANTILES(tbt, 1000)[OFFSET(500)], 2) AS p50_tbt,
49+
ROUND(APPROX_QUANTILES(tbt, 1000)[OFFSET(750)], 2) AS p75_tbt,
50+
ROUND(APPROX_QUANTILES(tbt, 1000)[OFFSET(900)], 2) AS p90_tbt,
51+
52+
-- FCP metrics
53+
ROUND(APPROX_QUANTILES(fcp, 1000)[OFFSET(100)], 2) AS p10_fcp,
54+
ROUND(APPROX_QUANTILES(fcp, 1000)[OFFSET(250)], 2) AS p25_fcp,
55+
ROUND(APPROX_QUANTILES(fcp, 1000)[OFFSET(500)], 2) AS p50_fcp,
56+
ROUND(APPROX_QUANTILES(fcp, 1000)[OFFSET(750)], 2) AS p75_fcp,
57+
ROUND(APPROX_QUANTILES(fcp, 1000)[OFFSET(900)], 2) AS p90_fcp,
58+
59+
-- TTI metrics
60+
ROUND(APPROX_QUANTILES(tti, 1000)[OFFSET(100)], 2) AS p10_tti,
61+
ROUND(APPROX_QUANTILES(tti, 1000)[OFFSET(250)], 2) AS p25_tti,
62+
ROUND(APPROX_QUANTILES(tti, 1000)[OFFSET(500)], 2) AS p50_tti,
63+
ROUND(APPROX_QUANTILES(tti, 1000)[OFFSET(750)], 2) AS p75_tti,
64+
ROUND(APPROX_QUANTILES(tti, 1000)[OFFSET(900)], 2) AS p90_tti,
65+
66+
-- Performance Score metrics
67+
ROUND(APPROX_QUANTILES(performance_score, 1000)[OFFSET(900)] * 100, 2) AS p10_performance_score,
68+
ROUND(APPROX_QUANTILES(performance_score, 1000)[OFFSET(750)] * 100, 2) AS p25_performance_score,
69+
ROUND(APPROX_QUANTILES(performance_score, 1000)[OFFSET(500)] * 100, 2) AS p50_performance_score,
70+
ROUND(APPROX_QUANTILES(performance_score, 1000)[OFFSET(250)] * 100, 2) AS p75_performance_score,
71+
ROUND(APPROX_QUANTILES(performance_score, 1000)[OFFSET(100)] * 100, 2) AS p90_performance_score,
72+
73+
-- Good CWV percentages
74+
ROUND(COUNTIF(lcp <= 2500) / COUNT(0) * 100, 2) AS good_lcp_percent,
75+
ROUND(COUNTIF(cls <= 0.1) / COUNT(0) * 100, 2) AS good_cls_percent,
76+
ROUND(COUNTIF(tbt <= 300) / COUNT(0) * 100, 2) AS good_tbt_percent,
77+
ROUND(COUNTIF(fcp <= 1800) / COUNT(0) * 100, 2) AS good_fcp_percent
78+
79+
FROM
80+
metrics_data
81+
GROUP BY
82+
date,
83+
client
84+
ORDER BY
85+
date DESC,
86+
client
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
SELECT
2+
percentile,
3+
client,
4+
is_root_page,
5+
APPROX_QUANTILES(CAST(JSON_VALUE(lighthouse.audits['unused-javascript'].details.overallSavingsBytes) AS INT64) / 1024, 1000)[OFFSET(percentile * 10)] AS unused_js_kbytes
6+
FROM
7+
`httparchive.crawl.pages`,
8+
UNNEST([10, 25, 50, 75, 90, 100]) AS percentile
9+
WHERE
10+
date = '2025-07-01'
11+
GROUP BY
12+
percentile,
13+
client,
14+
is_root_page
15+
ORDER BY
16+
client,
17+
is_root_page,
18+
percentile
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
SELECT
2+
client,
3+
is_root_page,
4+
COUNTIF(JSON_VALUE(lighthouse.audits['unminified-css'].score) IS NULL) AS null_count,
5+
COUNTIF(SAFE_CAST(JSON_VALUE(lighthouse.audits['unminified-css'].score) AS FLOAT64) >= 0.9) AS pass_count,
6+
COUNTIF(SAFE_CAST(JSON_VALUE(lighthouse.audits['unminified-css'].score) AS FLOAT64) < 0.9) AS fail_count,
7+
COUNT(0) AS total,
8+
COUNTIF(SAFE_CAST(JSON_VALUE(lighthouse.audits['unminified-css'].score) AS FLOAT64) >= 0.9) / COUNT(0) AS pct_pass,
9+
COUNTIF(SAFE_CAST(JSON_VALUE(lighthouse.audits['unminified-css'].score) AS FLOAT64) < 0.9) / COUNT(0) AS pct_fail
10+
FROM
11+
`httparchive.crawl.pages`
12+
WHERE
13+
date = '2025-07-01'
14+
GROUP BY
15+
client,
16+
is_root_page
17+
ORDER BY
18+
client,
19+
is_root_page,
20+
null_count,
21+
pass_count,
22+
fail_count
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
SELECT
2+
client,
3+
is_root_page,
4+
COUNTIF(JSON_VALUE(lighthouse.audits['unminified-javascript'].score) IS NULL) AS null_count,
5+
COUNTIF(SAFE_CAST(JSON_VALUE(lighthouse.audits['unminified-javascript'].score) AS FLOAT64) >= 0.9) AS pass_count,
6+
COUNTIF(SAFE_CAST(JSON_VALUE(lighthouse.audits['unminified-javascript'].score) AS FLOAT64) < 0.9) AS fail_count,
7+
COUNT(0) AS total,
8+
COUNTIF(SAFE_CAST(JSON_VALUE(lighthouse.audits['unminified-javascript'].score) AS FLOAT64) >= 0.9) / COUNT(0) AS pct_pass,
9+
COUNTIF(SAFE_CAST(JSON_VALUE(lighthouse.audits['unminified-javascript'].score) AS FLOAT64) < 0.9) / COUNT(0) AS pct_fail
10+
FROM
11+
`httparchive.crawl.pages`
12+
WHERE
13+
date = '2025-07-01'
14+
GROUP BY
15+
client,
16+
is_root_page
17+
ORDER BY
18+
client,
19+
is_root_page,
20+
null_count,
21+
pass_count,
22+
fail_count

0 commit comments

Comments
 (0)