diff --git a/sql/2020/09_Performance/lh5_performance_score_distribution.sql b/sql/2020/09_Performance/lh5_performance_score_distribution.sql new file mode 100644 index 00000000000..3a80b25e3e0 --- /dev/null +++ b/sql/2020/09_Performance/lh5_performance_score_distribution.sql @@ -0,0 +1,14 @@ +#standardSQL +# Distribution of LH5 performance score. + +SELECT + JSON_EXTRACT_SCALAR(report, '$.categories.performance.score') AS score, + COUNT(0) AS freq, + SUM(COUNT(0)) OVER () AS total, + COUNT(0) / SUM(COUNT(0)) OVER () AS pct +FROM + `httparchive.lighthouse.2019_07_01_mobile` +GROUP BY + score +ORDER BY + score diff --git a/sql/2020/09_Performance/lh6_performance_score_distribution.sql b/sql/2020/09_Performance/lh6_performance_score_distribution.sql new file mode 100644 index 00000000000..5f6d898db7b --- /dev/null +++ b/sql/2020/09_Performance/lh6_performance_score_distribution.sql @@ -0,0 +1,14 @@ +#standardSQL +# Distribution of LH6 performance score. + +SELECT + JSON_EXTRACT_SCALAR(report, '$.categories.performance.score') AS score, + COUNT(0) AS freq, + SUM(COUNT(0)) OVER () AS total, + COUNT(0) / SUM(COUNT(0)) OVER () AS pct +FROM + `httparchive.lighthouse.2020_09_01_mobile` +GROUP BY + score +ORDER BY + score diff --git a/sql/2020/09_Performance/lh6_vs_lh5_performance_score_01.sql b/sql/2020/09_Performance/lh6_vs_lh5_performance_score_01.sql new file mode 100644 index 00000000000..12f01f17354 --- /dev/null +++ b/sql/2020/09_Performance/lh6_vs_lh5_performance_score_01.sql @@ -0,0 +1,21 @@ +#standardSQL +# Calculates percentile for delta of LH5 and LH6 performance score for mobile + +SELECT + percentile, + APPROX_QUANTILES(perf_score_delta, 1000)[OFFSET(percentile * 10)] AS perf_score_delta +FROM ( + SELECT + perf_score_lh6 - perf_score_lh5 AS perf_score_delta + FROM + ( + SELECT + CAST(JSON_EXTRACT(lh6.report, '$.categories.performance.score') AS NUMERIC) AS perf_score_lh6, + CAST(JSON_EXTRACT(lh5.report, '$.categories.performance.score') AS NUMERIC) AS perf_score_lh5 + FROM `httparchive.lighthouse.2020_09_01_mobile` lh6 + JOIN `httparchive.lighthouse.2019_07_01_mobile` lh5 ON lh5.url=lh6.url + ) +), +UNNEST([0, 10, 25, 50, 75, 90, 100]) AS percentile +GROUP BY percentile +ORDER BY percentile diff --git a/sql/2020/09_Performance/lh6_vs_lh5_performance_score_02.sql b/sql/2020/09_Performance/lh6_vs_lh5_performance_score_02.sql new file mode 100644 index 00000000000..0cd98215338 --- /dev/null +++ b/sql/2020/09_Performance/lh6_vs_lh5_performance_score_02.sql @@ -0,0 +1,30 @@ +#standardSQL + +# Calculates percentage of sites where the performance score changed low ( < 10), medium (10-30) or big (> 30) between +# LH 5 and 6 versions. + +SELECT + SAFE_DIVIDE(small_change, small_change + mid_change + big_change) AS small, + SAFE_DIVIDE(mid_change, small_change + mid_change + big_change) AS avg, + SAFE_DIVIDE(big_change, small_change + mid_change + big_change) AS big +FROM ( + SELECT + COUNTIF(perf_score_delta <= 0.1) AS small_change, + COUNTIF(perf_score_delta > 0.1 AND perf_score_delta <= 0.3) AS mid_change, + COUNTIF(perf_score_delta > 0.3) AS big_change + FROM + ( + SELECT + perf_score_lh6, + perf_score_lh5, + (perf_score_lh6 - perf_score_lh5) AS perf_score_delta + FROM + ( + SELECT + CAST(JSON_EXTRACT(lh6.report, '$.categories.performance.score') AS NUMERIC) AS perf_score_lh6, + CAST(JSON_EXTRACT(lh5.report, '$.categories.performance.score') AS NUMERIC) AS perf_score_lh5 + FROM `httparchive.lighthouse.2020_09_01_mobile` lh6 + JOIN `httparchive.lighthouse.2019_07_01_mobile` lh5 ON lh5.url=lh6.url + ) + ) +) diff --git a/sql/2020/09_Performance/lighthouse_performace_audits.sql b/sql/2020/09_Performance/lighthouse_performace_audits.sql new file mode 100644 index 00000000000..ce3d0f339dd --- /dev/null +++ b/sql/2020/09_Performance/lighthouse_performace_audits.sql @@ -0,0 +1,42 @@ +#standardSQL +# Get summary of all lighthouse scores for a category +# Note scores, weightings, groups and descriptions may be off in mixed months when new versions of Lighthouse roles out + +CREATE TEMPORARY FUNCTION getAudits(report STRING, category STRING) +RETURNS ARRAY> LANGUAGE js AS ''' +var $ = JSON.parse(report); +var auditrefs = $.categories[category].auditRefs; +var audits = $.audits; +$ = null; +var results = []; +for (auditref of auditrefs) { + results.push({ + id: auditref.id, + weight: auditref.weight, + audit_group: auditref.group, + description: audits[auditref.id].description, + score: audits[auditref.id].score + }); +} +return results; +'''; + +SELECT + audits.id AS id, + COUNTIF(audits.score > 0) AS num_pages, + COUNT(0) AS total, + COUNTIF(audits.score IS NOT NULL) AS total_applicable, + SAFE_DIVIDE(COUNTIF(audits.score > 0), COUNTIF(audits.score IS NOT NULL)) AS pct, + APPROX_QUANTILES(audits.weight, 100)[OFFSET(50)] AS median_weight, + MAX(audits.audit_group) AS audit_group, + MAX(audits.description) AS description +FROM + `httparchive.lighthouse.2020_09_01_mobile`, + UNNEST(getAudits(report, "performance")) AS audits +WHERE + LENGTH(report) < 20000000 # necessary to avoid out of memory issues. Excludes 16 very large results +GROUP BY + audits.id +ORDER BY + median_weight DESC, + id diff --git a/sql/2020/09_Performance/median_lcp_score_by_month.sql b/sql/2020/09_Performance/median_lcp_score_by_month.sql new file mode 100644 index 00000000000..58afc6fc359 --- /dev/null +++ b/sql/2020/09_Performance/median_lcp_score_by_month.sql @@ -0,0 +1,16 @@ +#standardSQL +# Median of Largest contentful paint 75% score by month + +SELECT + date, + device, + APPROX_QUANTILES(p75_lcp, 1000 RESPECT NULLS)[OFFSET(500)] AS median_p75_lcp, +FROM + `chrome-ux-report.materialized.device_summary` +WHERE + date >= '2019-09-01' + AND date <= '2020-08-01' + AND device IN ('desktop','phone') +GROUP BY + date, + device diff --git a/sql/2020/09_Performance/offline_origins.sql b/sql/2020/09_Performance/offline_origins.sql new file mode 100644 index 00000000000..9085802995a --- /dev/null +++ b/sql/2020/09_Performance/offline_origins.sql @@ -0,0 +1,16 @@ +#standardSQL +# Offline origins + +SELECT + total_origins, + offline_origins, + offline_origins/total_origins AS pct_offline_origins +FROM ( + SELECT + COUNT(DISTINCT origin) AS total_origins, + COUNT(DISTINCT IF(offlineDensity > 0, origin, NULL)) AS offline_origins, + FROM + `chrome-ux-report.materialized.metrics_summary` + WHERE + date = '2020-08-01' +) diff --git a/sql/2020/09_Performance/performance_observer.sql b/sql/2020/09_Performance/performance_observer.sql new file mode 100644 index 00000000000..d9c410a28d0 --- /dev/null +++ b/sql/2020/09_Performance/performance_observer.sql @@ -0,0 +1,13 @@ +#standardSQL +# Percent of pages using Performance observer + +SELECT + client, + num_urls, + total_urls, + pct_urls +FROM + `httparchive.blink_features.usage` +WHERE + yyyymmdd = '20200801' AND + feature = 'PerformanceObserverForWindow' diff --git a/sql/2020/09_Performance/web_vitals_by_country.sql b/sql/2020/09_Performance/web_vitals_by_country.sql new file mode 100644 index 00000000000..d80b7f328f1 --- /dev/null +++ b/sql/2020/09_Performance/web_vitals_by_country.sql @@ -0,0 +1,154 @@ +#standardSQL +# Core WebVitals by country + +CREATE TEMP FUNCTION IS_GOOD (good FLOAT64, needs_improvement FLOAT64, poor FLOAT64) RETURNS BOOL AS ( + SAFE_DIVIDE(good, (good + needs_improvement + poor)) >= 0.75 +); + +CREATE TEMP FUNCTION IS_POOR (good FLOAT64, needs_improvement FLOAT64, poor FLOAT64) RETURNS BOOL AS ( + SAFE_DIVIDE(poor, (good + needs_improvement + poor)) >= 0.25 +); + +CREATE TEMP FUNCTION IS_NI (good FLOAT64, needs_improvement FLOAT64, poor FLOAT64) RETURNS BOOL AS ( + NOT IS_GOOD(good, needs_improvement, poor) AND + NOT IS_POOR(good, needs_improvement, poor) +); + +CREATE TEMP FUNCTION IS_NON_ZERO (good FLOAT64, needs_improvement FLOAT64, poor FLOAT64) RETURNS BOOL AS ( + good + needs_improvement + poor > 0 +); + +WITH + base AS ( + SELECT +  origin, + country_code, + + SUM(fast_fid) / SUM(fast_fid + avg_fid + slow_fid) AS fast_fid, + SUM(avg_fid) / SUM(fast_fid + avg_fid + slow_fid) AS avg_fid, + SUM(slow_fid) / SUM(fast_fid + avg_fid + slow_fid) AS slow_fid, + + SUM(fast_lcp) / SUM(fast_lcp + avg_lcp + slow_lcp) AS fast_lcp, + SUM(avg_lcp) / SUM(fast_lcp + avg_lcp + slow_lcp) AS avg_lcp, + SUM(slow_lcp) / SUM(fast_lcp + avg_lcp + slow_lcp) AS slow_lcp, + + SUM(small_cls) / SUM(small_cls + medium_cls + large_cls) AS small_cls, + SUM(medium_cls) / SUM(small_cls + medium_cls + large_cls) AS medium_cls, + SUM(large_cls) / SUM(small_cls + medium_cls + large_cls) AS large_cls, + + SUM(fast_fcp) / SUM(fast_fcp + avg_fcp + slow_fcp) AS fast_fcp, + SUM(avg_fcp) / SUM(fast_fcp + avg_fcp + slow_fcp) AS avg_fcp, + SUM(slow_fcp) / SUM(fast_fcp + avg_fcp + slow_fcp) AS slow_fcp, + + SUM(fast_ttfb) / SUM(fast_ttfb + avg_ttfb + slow_ttfb) AS fast_ttfb, + SUM(avg_ttfb) / SUM(fast_ttfb + avg_ttfb + slow_ttfb) AS avg_ttfb, + SUM(slow_ttfb) / SUM(fast_ttfb + avg_ttfb + slow_ttfb) AS slow_ttfb, + + FROM + `chrome-ux-report.materialized.country_summary` + WHERE + yyyymm = 202008 + GROUP BY + origin, + country_code + ) + +SELECT +  `chrome-ux-report`.experimental.GET_COUNTRY(country_code) AS country, + + COUNT(DISTINCT origin) AS total_origins, + + SAFE_DIVIDE( + COUNT(DISTINCT IF( + IS_GOOD(fast_fid, avg_fid, slow_fid) AND + IS_GOOD(fast_lcp, avg_lcp, slow_lcp) AND + IS_GOOD(small_cls, medium_cls, large_cls), origin, NULL)), + COUNT(DISTINCT IF( + IS_NON_ZERO(fast_fid, avg_fid, slow_fid) AND + IS_NON_ZERO(fast_lcp, avg_lcp, slow_lcp) AND + IS_NON_ZERO(small_cls, medium_cls, large_cls), origin, NULL))) AS pct_cwv_good, + + SAFE_DIVIDE( + COUNT(DISTINCT IF( + IS_GOOD(fast_lcp, avg_lcp, slow_lcp), origin, NULL)), + COUNT(DISTINCT IF( + IS_NON_ZERO(fast_lcp, avg_lcp, slow_lcp), origin, NULL))) AS pct_lcp_good, + SAFE_DIVIDE( + COUNT(DISTINCT IF( + IS_NI(fast_lcp, avg_lcp, slow_lcp), origin, NULL)), + COUNT(DISTINCT IF( + IS_NON_ZERO(fast_lcp, avg_lcp, slow_lcp), origin, NULL))) AS pct_lcp_ni, + SAFE_DIVIDE( + COUNT(DISTINCT IF( + IS_POOR(fast_lcp, avg_lcp, slow_lcp), origin, NULL)), + COUNT(DISTINCT IF( + IS_NON_ZERO(fast_lcp, avg_lcp, slow_lcp), origin, NULL))) AS pct_lcp_poor, + + SAFE_DIVIDE( + COUNT(DISTINCT IF( + IS_GOOD(fast_fid, avg_fid, slow_fid), origin, NULL)), + COUNT(DISTINCT IF( + IS_NON_ZERO(fast_fid, avg_fid, slow_fid), origin, NULL))) AS pct_fid_good, + SAFE_DIVIDE( + COUNT(DISTINCT IF( + IS_NI(fast_fid, avg_fid, slow_fid), origin, NULL)), + COUNT(DISTINCT IF( + IS_NON_ZERO(fast_fid, avg_fid, slow_fid), origin, NULL))) AS pct_fid_ni, + SAFE_DIVIDE( + COUNT(DISTINCT IF( + IS_POOR(fast_fid, avg_fid, slow_fid), origin, NULL)), + COUNT(DISTINCT IF( + IS_NON_ZERO(fast_fid, avg_fid, slow_fid), origin, NULL))) AS pct_fid_poor, + + SAFE_DIVIDE( + COUNT(DISTINCT IF( + IS_GOOD(small_cls, medium_cls, large_cls), origin, NULL)), + COUNT(DISTINCT IF( + IS_NON_ZERO(small_cls, medium_cls, large_cls), origin, NULL))) AS pct_cls_good, + SAFE_DIVIDE( + COUNT(DISTINCT IF( + IS_NI(small_cls, medium_cls, large_cls), origin, NULL)), + COUNT(DISTINCT IF( + IS_NON_ZERO(small_cls, medium_cls, large_cls), origin, NULL))) AS pct_cls_ni, + SAFE_DIVIDE( + COUNT(DISTINCT IF( + IS_POOR(small_cls, medium_cls, large_cls), origin, NULL)), + COUNT(DISTINCT IF( + IS_NON_ZERO(small_cls, medium_cls, large_cls), origin, NULL))) AS pct_cls_poor, + + SAFE_DIVIDE( + COUNT(DISTINCT IF( + IS_GOOD(fast_fcp, avg_fcp, slow_fcp), origin, NULL)), + COUNT(DISTINCT IF( + IS_NON_ZERO(fast_fcp, avg_fcp, slow_fcp), origin, NULL))) AS pct_fcp_good, + SAFE_DIVIDE( + COUNT(DISTINCT IF( + IS_NI(fast_fcp, avg_fcp, slow_fcp), origin, NULL)), + COUNT(DISTINCT IF( + IS_NON_ZERO(fast_fcp, avg_fcp, slow_fcp), origin, NULL))) AS pct_fcp_ni, + SAFE_DIVIDE( + COUNT(DISTINCT IF( + IS_POOR(fast_fcp, avg_fcp, slow_fcp), origin, NULL)), + COUNT(DISTINCT IF( + IS_NON_ZERO(fast_fcp, avg_fcp, slow_fcp), origin, NULL))) AS pct_fcp_poor, + + SAFE_DIVIDE( + COUNT(DISTINCT IF( + IS_GOOD(fast_ttfb, avg_ttfb, slow_ttfb), origin, NULL)), + COUNT(DISTINCT IF( + IS_NON_ZERO(fast_ttfb, avg_ttfb, slow_ttfb), origin, NULL))) AS pct_ttfb_good, + SAFE_DIVIDE( + COUNT(DISTINCT IF( + IS_NI(fast_ttfb, avg_ttfb, slow_ttfb), origin, NULL)), + COUNT(DISTINCT IF( + IS_NON_ZERO(fast_ttfb, avg_ttfb, slow_ttfb), origin, NULL))) AS pct_ttfb_ni, + SAFE_DIVIDE( + COUNT(DISTINCT IF( + IS_POOR(fast_ttfb, avg_ttfb, slow_ttfb), origin, NULL)), + COUNT(DISTINCT IF( + IS_NON_ZERO(fast_ttfb, avg_ttfb, slow_ttfb), origin, NULL))) AS pct_ttfb_poor, + +FROM + base +GROUP BY +  country diff --git a/sql/2020/09_Performance/web_vitals_by_device.sql b/sql/2020/09_Performance/web_vitals_by_device.sql new file mode 100644 index 00000000000..c801161bfbc --- /dev/null +++ b/sql/2020/09_Performance/web_vitals_by_device.sql @@ -0,0 +1,155 @@ +#standardSQL +# Core WebVitals by device + +CREATE TEMP FUNCTION IS_GOOD (good FLOAT64, needs_improvement FLOAT64, poor FLOAT64) RETURNS BOOL AS ( + good / (good + needs_improvement + poor) >= 0.75 +); + +CREATE TEMP FUNCTION IS_NI (good FLOAT64, needs_improvement FLOAT64, poor FLOAT64) RETURNS BOOL AS ( + good / (good + needs_improvement + poor) < 0.75 + AND poor / (good + needs_improvement + poor) < 0.25 +); + +CREATE TEMP FUNCTION IS_POOR (good FLOAT64, needs_improvement FLOAT64, poor FLOAT64) RETURNS BOOL AS ( + poor / (good + needs_improvement + poor) >= 0.25 +); + +CREATE TEMP FUNCTION IS_NON_ZERO (good FLOAT64, needs_improvement FLOAT64, poor FLOAT64) RETURNS BOOL AS ( + good + needs_improvement + poor > 0 +); + +WITH + base AS ( + SELECT + date, +  origin, + device, + + fast_fid, + avg_fid, + slow_fid, + + fast_lcp, + avg_lcp, + slow_lcp, + + small_cls, + medium_cls, + large_cls, + + fast_fcp, + avg_fcp, + slow_fcp, + + fast_ttfb, + avg_ttfb, + slow_ttfb + + FROM + `chrome-ux-report.materialized.device_summary` + WHERE + device IN ('desktop','phone') + AND date IN ('2019-08-01', '2020-08-01') + ) + +SELECT + date, +  device, + + COUNT(DISTINCT origin) AS total_origins, + + SAFE_DIVIDE( + COUNT(DISTINCT IF( + IS_GOOD(fast_fid, avg_fid, slow_fid) AND + IS_GOOD(fast_lcp, avg_lcp, slow_lcp) AND + IS_GOOD(small_cls, medium_cls, large_cls), origin, NULL)), + COUNT(DISTINCT IF( + IS_NON_ZERO(fast_fid, avg_fid, slow_fid) AND + IS_NON_ZERO(fast_lcp, avg_lcp, slow_lcp) AND + IS_NON_ZERO(small_cls, medium_cls, large_cls), origin, NULL))) AS pct_cwv_good, + + SAFE_DIVIDE( + COUNT(DISTINCT IF( + IS_GOOD(fast_lcp, avg_lcp, slow_lcp), origin, NULL)), + COUNT(DISTINCT IF( + IS_NON_ZERO(fast_lcp, avg_lcp, slow_lcp), origin, NULL))) AS pct_lcp_good, + SAFE_DIVIDE( + COUNT(DISTINCT IF( + IS_NI(fast_lcp, avg_lcp, slow_lcp), origin, NULL)), + COUNT(DISTINCT IF( + IS_NON_ZERO(fast_lcp, avg_lcp, slow_lcp), origin, NULL))) AS pct_lcp_ni, + SAFE_DIVIDE( + COUNT(DISTINCT IF( + IS_POOR(fast_lcp, avg_lcp, slow_lcp), origin, NULL)), + COUNT(DISTINCT IF( + IS_NON_ZERO(fast_lcp, avg_lcp, slow_lcp), origin, NULL))) AS pct_lcp_poor, + + SAFE_DIVIDE( + COUNT(DISTINCT IF( + IS_GOOD(fast_fid, avg_fid, slow_fid), origin, NULL)), + COUNT(DISTINCT IF( + IS_NON_ZERO(fast_fid, avg_fid, slow_fid), origin, NULL))) AS pct_fid_good, + SAFE_DIVIDE( + COUNT(DISTINCT IF( + IS_NI(fast_fid, avg_fid, slow_fid), origin, NULL)), + COUNT(DISTINCT IF( + IS_NON_ZERO(fast_fid, avg_fid, slow_fid), origin, NULL))) AS pct_fid_ni, + SAFE_DIVIDE( + COUNT(DISTINCT IF( + IS_POOR(fast_fid, avg_fid, slow_fid), origin, NULL)), + COUNT(DISTINCT IF( + IS_NON_ZERO(fast_fid, avg_fid, slow_fid), origin, NULL))) AS pct_fid_poor, + + SAFE_DIVIDE( + COUNT(DISTINCT IF( + IS_GOOD(small_cls, medium_cls, large_cls), origin, NULL)), + COUNT(DISTINCT IF( + IS_NON_ZERO(small_cls, medium_cls, large_cls), origin, NULL))) AS pct_cls_good, + SAFE_DIVIDE( + COUNT(DISTINCT IF( + IS_NI(small_cls, medium_cls, large_cls), origin, NULL)), + COUNT(DISTINCT IF( + IS_NON_ZERO(small_cls, medium_cls, large_cls), origin, NULL))) AS pct_cls_ni, + SAFE_DIVIDE( + COUNT(DISTINCT IF( + IS_POOR(small_cls, medium_cls, large_cls), origin, NULL)), + COUNT(DISTINCT IF( + IS_NON_ZERO(small_cls, medium_cls, large_cls), origin, NULL))) AS pct_cls_poor, + + SAFE_DIVIDE( + COUNT(DISTINCT IF( + IS_GOOD(fast_fcp, avg_fcp, slow_fcp), origin, NULL)), + COUNT(DISTINCT IF( + IS_NON_ZERO(fast_fcp, avg_fcp, slow_fcp), origin, NULL))) AS pct_fcp_good, + SAFE_DIVIDE( + COUNT(DISTINCT IF( + IS_NI(fast_fcp, avg_fcp, slow_fcp), origin, NULL)), + COUNT(DISTINCT IF( + IS_NON_ZERO(fast_fcp, avg_fcp, slow_fcp), origin, NULL))) AS pct_fcp_ni, + SAFE_DIVIDE( + COUNT(DISTINCT IF( + IS_POOR(fast_fcp, avg_fcp, slow_fcp), origin, NULL)), + COUNT(DISTINCT IF( + IS_NON_ZERO(fast_fcp, avg_fcp, slow_fcp), origin, NULL))) AS pct_fcp_poor, + + SAFE_DIVIDE( + COUNT(DISTINCT IF( + IS_GOOD(fast_ttfb, avg_ttfb, slow_ttfb), origin, NULL)), + COUNT(DISTINCT IF( + IS_NON_ZERO(fast_ttfb, avg_ttfb, slow_ttfb), origin, NULL))) AS pct_ttfb_good, + SAFE_DIVIDE( + COUNT(DISTINCT IF( + IS_NI(fast_ttfb, avg_ttfb, slow_ttfb), origin, NULL)), + COUNT(DISTINCT IF( + IS_NON_ZERO(fast_ttfb, avg_ttfb, slow_ttfb), origin, NULL))) AS pct_ttfb_ni, + SAFE_DIVIDE( + COUNT(DISTINCT IF( + IS_POOR(fast_ttfb, avg_ttfb, slow_ttfb), origin, NULL)), + COUNT(DISTINCT IF( + IS_NON_ZERO(fast_ttfb, avg_ttfb, slow_ttfb), origin, NULL))) AS pct_ttfb_poor, + +FROM + base +GROUP BY + date, +  device diff --git a/sql/2020/09_Performance/web_vitals_by_ect.sql b/sql/2020/09_Performance/web_vitals_by_ect.sql new file mode 100644 index 00000000000..8dd4ce812b8 --- /dev/null +++ b/sql/2020/09_Performance/web_vitals_by_ect.sql @@ -0,0 +1,259 @@ +#standardSQL +# WebVitals by effective connection type + +CREATE TEMP FUNCTION IS_GOOD (good FLOAT64, needs_improvement FLOAT64, poor FLOAT64) RETURNS BOOL AS ( + SAFE_DIVIDE(good, (good + needs_improvement + poor)) >= 0.75 +); + +CREATE TEMP FUNCTION IS_NI (good FLOAT64, needs_improvement FLOAT64, poor FLOAT64) RETURNS BOOL AS ( + SAFE_DIVIDE(good, (good + needs_improvement + poor)) < 0.75 AND + SAFE_DIVIDE(poor, (good + needs_improvement + poor)) < 0.25 +); + +CREATE TEMP FUNCTION IS_POOR (good FLOAT64, needs_improvement FLOAT64, poor FLOAT64) RETURNS BOOL AS ( + SAFE_DIVIDE(poor, (good + needs_improvement + poor)) >= 0.25 +); + +CREATE TEMP FUNCTION IS_NON_ZERO (good FLOAT64, needs_improvement FLOAT64, poor FLOAT64) RETURNS BOOL AS ( + good + needs_improvement + poor > 0 +); + +WITH + base AS ( + SELECT +  origin, + effective_connection_type.name AS network, + layout_instability, + largest_contentful_paint, + first_input, + first_contentful_paint, + experimental.time_to_first_byte AS time_to_first_byte + FROM + `chrome-ux-report.all.202008` + ), + cls AS ( + SELECT + origin, + network, + SUM(IF(bin.start < 0.1, bin.density, 0)) AS small, + SUM(IF(bin.start > 0.1 AND bin.start < 0.25, bin.density, 0)) AS medium, + SUM(IF(bin.start >= 0.25, bin.density, 0)) AS large, + `chrome-ux-report`.experimental.PERCENTILE_NUMERIC(ARRAY_AGG(bin), 75) AS p75 + FROM + base + LEFT JOIN + UNNEST(layout_instability.cumulative_layout_shift.histogram.bin) AS bin + GROUP BY + origin, + network + ), + lcp AS ( + SELECT + origin, + network, + SUM(IF(bin.start < 2500, bin.density, 0)) AS fast, + SUM(IF(bin.start >= 2500 AND bin.start < 4000, bin.density, 0)) AS avg, + SUM(IF(bin.start >= 4000, bin.density, 0)) AS slow, + `chrome-ux-report`.experimental.PERCENTILE(ARRAY_AGG(bin), 75) AS p75 + FROM + base + LEFT JOIN + UNNEST(largest_contentful_paint.histogram.bin) AS bin + GROUP BY + origin, + network + ), + fid AS ( + SELECT + origin, + network, + SUM(IF(bin.start < 100, bin.density, 0)) AS fast, + SUM(IF(bin.start >= 100 AND bin.start < 300, bin.density, 0)) AS avg, + SUM(IF(bin.start >= 300, bin.density, 0)) AS slow, + `chrome-ux-report`.experimental.PERCENTILE(ARRAY_AGG(bin), 75) AS p75 + FROM + base + LEFT JOIN + UNNEST(first_input.delay.histogram.bin) AS bin + GROUP BY + origin, + network + ), + fcp AS ( + SELECT + origin, + network, +   SUM(IF(bin.start < 1500, bin.density, 0)) AS fast, +   SUM(IF(bin.start >= 1500 AND bin.start < 2500, bin.density, 0)) AS avg, +   SUM(IF(bin.start >= 2500, bin.density, 0)) AS slow, + `chrome-ux-report`.experimental.PERCENTILE(ARRAY_AGG(bin), 75) AS p75 + FROM +   base + LEFT JOIN +   UNNEST(first_contentful_paint.histogram.bin) AS bin + GROUP BY + origin, + network + ), + ttfb AS ( + SELECT + origin, + network, +   SUM(IF(bin.start < 500, bin.density, 0)) AS fast, +   SUM(IF(bin.start >= 500 AND bin.start < 1500, bin.density, 0)) AS avg, +   SUM(IF(bin.start >= 1500, bin.density, 0)) AS slow, + `chrome-ux-report`.experimental.PERCENTILE(ARRAY_AGG(bin), 75) AS p75 + FROM + base + LEFT JOIN +   UNNEST(time_to_first_byte.histogram.bin) AS bin + GROUP BY + origin, + network + ), + granular_metrics AS ( + SELECT + origin, + network, + cls.small AS small_cls, + cls.medium AS medium_cls, + cls.large AS large_cls, + cls.p75 AS p75_cls, + + lcp.fast AS fast_lcp, + lcp.avg AS avg_lcp, + lcp.slow AS slow_lcp, + lcp.p75 AS p75_lcp, + + fid.fast AS fast_fid, + fid.avg AS avg_fid, + fid.slow AS slow_fid, + fid.p75 AS p75_fid, + + fcp.fast AS fast_fcp, + fcp.avg AS avg_fcp, + fcp.slow AS slow_fcp, + fcp.p75 AS p75_fcp, + + ttfb.fast AS fast_ttfb, + ttfb.avg AS avg_ttfb, + ttfb.slow AS slow_ttfb, + ttfb.p75 AS p75_ttfb, + FROM + cls + LEFT JOIN + lcp + USING + (origin, network) + LEFT JOIN + fid + USING + (origin, network) + LEFT JOIN + fcp + USING + (origin, network) + LEFT JOIN + ttfb + USING + (origin, network)) + +SELECT + network, + + COUNT(DISTINCT origin) AS total_origins, + + SAFE_DIVIDE( + COUNT(DISTINCT IF( + IS_GOOD(fast_fid, avg_fid, slow_fid) AND + IS_GOOD(fast_lcp, avg_lcp, slow_lcp) AND + IS_GOOD(small_cls, medium_cls, large_cls), origin, NULL)), + COUNT(DISTINCT IF( + IS_NON_ZERO(fast_fid, avg_fid, slow_fid) AND + IS_NON_ZERO(fast_lcp, avg_lcp, slow_lcp) AND + IS_NON_ZERO(small_cls, medium_cls, large_cls), origin, NULL))) AS pct_cwv_good, + + SAFE_DIVIDE( + COUNT(DISTINCT IF( + IS_GOOD(fast_lcp, avg_lcp, slow_lcp), origin, NULL)), + COUNT(DISTINCT IF( + IS_NON_ZERO(fast_lcp, avg_lcp, slow_lcp), origin, NULL))) AS pct_lcp_good, + SAFE_DIVIDE( + COUNT(DISTINCT IF( + IS_NI(fast_lcp, avg_lcp, slow_lcp), origin, NULL)), + COUNT(DISTINCT IF( + IS_NON_ZERO(fast_lcp, avg_lcp, slow_lcp), origin, NULL))) AS pct_lcp_ni, + SAFE_DIVIDE( + COUNT(DISTINCT IF( + IS_POOR(fast_lcp, avg_lcp, slow_lcp), origin, NULL)), + COUNT(DISTINCT IF( + IS_NON_ZERO(fast_lcp, avg_lcp, slow_lcp), origin, NULL))) AS pct_lcp_poor, + + SAFE_DIVIDE( + COUNT(DISTINCT IF( + IS_GOOD(fast_fid, avg_fid, slow_fid), origin, NULL)), + COUNT(DISTINCT IF( + IS_NON_ZERO(fast_fid, avg_fid, slow_fid), origin, NULL))) AS pct_fid_good, + SAFE_DIVIDE( + COUNT(DISTINCT IF( + IS_NI(fast_fid, avg_fid, slow_fid), origin, NULL)), + COUNT(DISTINCT IF( + IS_NON_ZERO(fast_fid, avg_fid, slow_fid), origin, NULL))) AS pct_fid_ni, + SAFE_DIVIDE( + COUNT(DISTINCT IF( + IS_POOR(fast_fid, avg_fid, slow_fid), origin, NULL)), + COUNT(DISTINCT IF( + IS_NON_ZERO(fast_fid, avg_fid, slow_fid), origin, NULL))) AS pct_fid_poor, + + SAFE_DIVIDE( + COUNT(DISTINCT IF( + IS_GOOD(small_cls, medium_cls, large_cls), origin, NULL)), + COUNT(DISTINCT IF( + IS_NON_ZERO(small_cls, medium_cls, large_cls), origin, NULL))) AS pct_cls_good, + SAFE_DIVIDE( + COUNT(DISTINCT IF( + IS_NI(small_cls, medium_cls, large_cls), origin, NULL)), + COUNT(DISTINCT IF( + IS_NON_ZERO(small_cls, medium_cls, large_cls), origin, NULL))) AS pct_cls_ni, + SAFE_DIVIDE( + COUNT(DISTINCT IF( + IS_POOR(small_cls, medium_cls, large_cls), origin, NULL)), + COUNT(DISTINCT IF( + IS_NON_ZERO(small_cls, medium_cls, large_cls), origin, NULL))) AS pct_cls_poor, + + SAFE_DIVIDE( + COUNT(DISTINCT IF( + IS_GOOD(fast_fcp, avg_fcp, slow_fcp), origin, NULL)), + COUNT(DISTINCT IF( + IS_NON_ZERO(fast_fcp, avg_fcp, slow_fcp), origin, NULL))) AS pct_fcp_good, + SAFE_DIVIDE( + COUNT(DISTINCT IF( + IS_NI(fast_fcp, avg_fcp, slow_fcp), origin, NULL)), + COUNT(DISTINCT IF( + IS_NON_ZERO(fast_fcp, avg_fcp, slow_fcp), origin, NULL))) AS pct_fcp_ni, + SAFE_DIVIDE( + COUNT(DISTINCT IF( + IS_POOR(fast_fcp, avg_fcp, slow_fcp), origin, NULL)), + COUNT(DISTINCT IF( + IS_NON_ZERO(fast_fcp, avg_fcp, slow_fcp), origin, NULL))) AS pct_fcp_poor, + + SAFE_DIVIDE( + COUNT(DISTINCT IF( + IS_GOOD(fast_ttfb, avg_ttfb, slow_ttfb), origin, NULL)), + COUNT(DISTINCT IF( + IS_NON_ZERO(fast_ttfb, avg_ttfb, slow_ttfb), origin, NULL))) AS pct_ttfb_good, + SAFE_DIVIDE( + COUNT(DISTINCT IF( + IS_NI(fast_ttfb, avg_ttfb, slow_ttfb), origin, NULL)), + COUNT(DISTINCT IF( + IS_NON_ZERO(fast_ttfb, avg_ttfb, slow_ttfb), origin, NULL))) AS pct_ttfb_ni, + SAFE_DIVIDE( + COUNT(DISTINCT IF( + IS_POOR(fast_ttfb, avg_ttfb, slow_ttfb), origin, NULL)), + COUNT(DISTINCT IF( + IS_NON_ZERO(fast_ttfb, avg_ttfb, slow_ttfb), origin, NULL))) AS pct_ttfb_poor, + +FROM + granular_metrics +GROUP BY + network diff --git a/sql/2020/09_Performance/web_vitals_distribution_by_device.sql b/sql/2020/09_Performance/web_vitals_distribution_by_device.sql new file mode 100644 index 00000000000..b1938e53314 --- /dev/null +++ b/sql/2020/09_Performance/web_vitals_distribution_by_device.sql @@ -0,0 +1,185 @@ +#standardSQL +# WebVitals distribution by device + +WITH + base AS ( + SELECT + device, + + fast_fid, + avg_fid, + slow_fid, + + fast_lcp, + avg_lcp, + slow_lcp, + + small_cls, + medium_cls, + large_cls, + + fast_fcp, + avg_fcp, + slow_fcp, + + fast_ttfb, + avg_ttfb, + slow_ttfb, + + FROM + `chrome-ux-report.materialized.device_summary` + WHERE + device IN ('desktop','phone') AND + date = '2020-08-01' + ), +fid AS ( + SELECT + device, + fast_fid, + avg_fid, + slow_fid, + ROW_NUMBER() OVER (PARTITION BY device ORDER BY fast_fid DESC) AS row, + FROM ( + SELECT + device, + SAFE_DIVIDE(fast_fid, fast_fid + avg_fid + slow_fid) AS fast_fid, + SAFE_DIVIDE(avg_fid, fast_fid + avg_fid + slow_fid) AS avg_fid, + SAFE_DIVIDE(slow_fid, fast_fid + avg_fid + slow_fid) AS slow_fid, + ROW_NUMBER() OVER (PARTITION BY device ORDER BY fast_fid DESC) AS row, + COUNT(0) OVER (PARTITION BY device) AS n, + FROM + base + WHERE + fast_fid + avg_fid + slow_fid > 0) + WHERE + MOD(row, CAST(FLOOR(n / 1000) AS INT64)) = 0 +), +lcp AS ( + SELECT + device, + fast_lcp, + avg_lcp, + slow_lcp, + ROW_NUMBER() OVER (PARTITION BY device ORDER BY fast_lcp DESC) AS row, + FROM ( + SELECT + device, + SAFE_DIVIDE(fast_lcp, fast_lcp + avg_lcp + slow_lcp) AS fast_lcp, + SAFE_DIVIDE(avg_lcp, fast_lcp + avg_lcp + slow_lcp) AS avg_lcp, + SAFE_DIVIDE(slow_lcp, fast_lcp + avg_lcp + slow_lcp) AS slow_lcp, + ROW_NUMBER() OVER (PARTITION BY device ORDER BY fast_lcp DESC) AS row, + COUNT(0) OVER (PARTITION BY device) AS n, + FROM + base + WHERE + fast_lcp + avg_lcp + slow_lcp > 0) + WHERE + MOD(row, CAST(FLOOR(n / 1000) AS INT64)) = 0 +), +cls AS ( + SELECT + device, + small_cls, + medium_cls, + large_cls, + ROW_NUMBER() OVER (PARTITION BY device ORDER BY small_cls DESC) AS row, + FROM ( + SELECT + device, + SAFE_DIVIDE(small_cls, small_cls + medium_cls + large_cls) AS small_cls, + SAFE_DIVIDE(medium_cls, small_cls + medium_cls + large_cls) AS medium_cls, + SAFE_DIVIDE(large_cls, small_cls + medium_cls + large_cls) AS large_cls, + ROW_NUMBER() OVER (PARTITION BY device ORDER BY small_cls DESC) AS row, + COUNT(0) OVER (PARTITION BY device) AS n, + FROM + base + WHERE + small_cls + medium_cls + large_cls > 0) + WHERE + MOD(row, CAST(FLOOR(n / 1000) AS INT64)) = 0 +), +fcp AS ( + SELECT + device, + fast_fcp, + avg_fcp, + slow_fcp, + ROW_NUMBER() OVER (PARTITION BY device ORDER BY fast_fcp DESC) AS row, + FROM ( + SELECT + device, + SAFE_DIVIDE(fast_fcp, fast_fcp + avg_fcp + slow_fcp) AS fast_fcp, + SAFE_DIVIDE(avg_fcp, fast_fcp + avg_fcp + slow_fcp) AS avg_fcp, + SAFE_DIVIDE(slow_fcp, fast_fcp + avg_fcp + slow_fcp) AS slow_fcp, + ROW_NUMBER() OVER (PARTITION BY device ORDER BY fast_fcp DESC) AS row, + COUNT(0) OVER (PARTITION BY device) AS n, + FROM + base + WHERE + fast_fcp + avg_fcp + slow_fcp > 0) + WHERE + MOD(row, CAST(FLOOR(n / 1000) AS INT64)) = 0 +), +ttfb AS ( + SELECT + device, + fast_ttfb, + avg_ttfb, + slow_ttfb, + ROW_NUMBER() OVER (PARTITION BY device ORDER BY fast_ttfb DESC) AS row, + FROM ( + SELECT + device, + SAFE_DIVIDE(fast_ttfb, fast_ttfb + avg_ttfb + slow_ttfb) AS fast_ttfb, + SAFE_DIVIDE(avg_ttfb, fast_ttfb + avg_ttfb + slow_ttfb) AS avg_ttfb, + SAFE_DIVIDE(slow_ttfb, fast_ttfb + avg_ttfb + slow_ttfb) AS slow_ttfb, + ROW_NUMBER() OVER (PARTITION BY device ORDER BY fast_ttfb DESC) AS row, + COUNT(0) OVER (PARTITION BY device) AS n, + FROM + base + WHERE + fast_ttfb + avg_ttfb + slow_ttfb > 0) + WHERE + MOD(row, CAST(FLOOR(n / 1000) AS INT64)) = 0 +) + +SELECT + row, + device, + + fast_fid, + avg_fid, + slow_fid, + + small_cls, + medium_cls, + large_cls, + + fast_lcp, + avg_lcp, + slow_lcp, + + fast_fcp, + avg_fcp, + slow_fcp, + + fast_ttfb, + avg_ttfb, + slow_ttfb, +FROM + fid +FULL JOIN + lcp +USING (row, device) +FULL JOIN + cls +USING (row, device) +FULL JOIN + fcp +USING (row, device) +FULL JOIN + ttfb +USING (row, device) +ORDER BY + row, + device