Skip to content

Commit 0fe4cc1

Browse files
committed
cwv_by_shopify_theme
1 parent 5c1c78e commit 0fe4cc1

1 file changed

Lines changed: 202 additions & 0 deletions

File tree

Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
const pastMonth = constants.fnPastMonth(constants.currentMonth)
2+
3+
publish('cwv_by_shopify_theme', {
4+
schema: 'reports',
5+
type: 'table',
6+
tags: ['crux_ready']
7+
}).preOps(`
8+
CREATE TEMP FUNCTION IS_GOOD(good FLOAT64, needs_improvement FLOAT64, poor FLOAT64) RETURNS BOOL AS (
9+
good / (good + needs_improvement + poor) >= 0.75
10+
);
11+
12+
CREATE TEMP FUNCTION IS_POOR(good FLOAT64, needs_improvement FLOAT64, poor FLOAT64) RETURNS BOOL AS (
13+
poor / (good + needs_improvement + poor) > 0.25
14+
);
15+
16+
CREATE TEMP FUNCTION IS_NON_ZERO(good FLOAT64, needs_improvement FLOAT64, poor FLOAT64) RETURNS BOOL AS (
17+
good + needs_improvement + poor > 0
18+
);
19+
`).query(ctx => `
20+
WITH archive_pages AS (
21+
-- All Shopify shops in HTTPArchive
22+
SELECT
23+
client,
24+
page AS url,
25+
JSON_VALUE(custom_metrics.ecommerce.Shopify.theme.name) AS theme_name,
26+
JSON_VALUE(custom_metrics.ecommerce.Shopify.theme.theme_store_id) AS theme_store_id
27+
FROM ${ctx.ref('crawl', 'pages')}
28+
WHERE
29+
date = '${pastMonth}' ${constants.devRankFilter} AND
30+
is_root_page AND
31+
JSON_VALUE(custom_metrics.ecommerce.Shopify.theme.name) IS NOT NULL --first grab all shops for market share
32+
)
33+
34+
SELECT
35+
client,
36+
archive_pages.theme_store_id AS id,
37+
theme_names.theme_name AS top_theme_name,
38+
COUNT(DISTINCT origin) AS origins,
39+
-- Origins with good LCP divided by origins with any LCP.
40+
SAFE_DIVIDE(
41+
COUNT(DISTINCT IF(IS_GOOD(fast_lcp, avg_lcp, slow_lcp), origin, NULL)),
42+
COUNT(DISTINCT IF(IS_NON_ZERO(fast_lcp, avg_lcp, slow_lcp), origin, NULL))
43+
) AS pct_good_lcp,
44+
-- Origins with needs improvement are anything not good, nor poor.
45+
1 -
46+
SAFE_DIVIDE(
47+
COUNT(DISTINCT IF(IS_GOOD(fast_lcp, avg_lcp, slow_lcp), origin, NULL)),
48+
COUNT(DISTINCT IF(IS_NON_ZERO(fast_lcp, avg_lcp, slow_lcp), origin, NULL))
49+
)
50+
-
51+
SAFE_DIVIDE(
52+
COUNT(DISTINCT IF(IS_POOR(fast_lcp, avg_lcp, slow_lcp), origin, NULL)),
53+
COUNT(DISTINCT IF(IS_NON_ZERO(fast_lcp, avg_lcp, slow_lcp), origin, NULL)))
54+
AS pct_ni_lcp,
55+
-- Origins with poor LCP divided by origins with any LCP.
56+
SAFE_DIVIDE(
57+
COUNT(DISTINCT IF(IS_POOR(fast_lcp, avg_lcp, slow_lcp), origin, NULL)),
58+
COUNT(DISTINCT IF(IS_NON_ZERO(fast_lcp, avg_lcp, slow_lcp), origin, NULL))
59+
) AS pct_poor_lcp,
60+
61+
-- Origins with good TTFB divided by origins with any TTFB.
62+
SAFE_DIVIDE(
63+
COUNT(DISTINCT IF(IS_GOOD(fast_ttfb, avg_ttfb, slow_ttfb), origin, NULL)),
64+
COUNT(DISTINCT IF(IS_NON_ZERO(fast_ttfb, avg_ttfb, slow_ttfb), origin, NULL))
65+
) AS pct_good_ttfb,
66+
-- Origins with needs improvement are anything not good, nor poor.
67+
1 -
68+
SAFE_DIVIDE(
69+
COUNT(DISTINCT IF(IS_GOOD(fast_ttfb, avg_ttfb, slow_ttfb), origin, NULL)),
70+
COUNT(DISTINCT IF(IS_NON_ZERO(fast_ttfb, avg_ttfb, slow_ttfb), origin, NULL))
71+
)
72+
-
73+
SAFE_DIVIDE(
74+
COUNT(DISTINCT IF(IS_POOR(fast_ttfb, avg_ttfb, slow_ttfb), origin, NULL)),
75+
COUNT(DISTINCT IF(IS_NON_ZERO(fast_ttfb, avg_ttfb, slow_ttfb), origin, NULL)))
76+
AS pct_ni_ttfb,
77+
-- Origins with poor TTFB divided by origins with any TTFB.
78+
SAFE_DIVIDE(
79+
COUNT(DISTINCT IF(IS_POOR(fast_ttfb, avg_ttfb, slow_ttfb), origin, NULL)),
80+
COUNT(DISTINCT IF(IS_NON_ZERO(fast_ttfb, avg_ttfb, slow_ttfb), origin, NULL))
81+
) AS pct_poor_ttfb,
82+
83+
-- Origins with good FCP divided by origins with any FCP.
84+
SAFE_DIVIDE(
85+
COUNT(DISTINCT IF(IS_GOOD(fast_fcp, avg_fcp, slow_fcp), origin, NULL)),
86+
COUNT(DISTINCT IF(IS_NON_ZERO(fast_fcp, avg_fcp, slow_fcp), origin, NULL))
87+
) AS pct_good_fcp,
88+
-- Origins with needs improvement are anything not good, nor poor.
89+
1 -
90+
SAFE_DIVIDE(
91+
COUNT(DISTINCT IF(IS_GOOD(fast_fcp, avg_fcp, slow_fcp), origin, NULL)),
92+
COUNT(DISTINCT IF(IS_NON_ZERO(fast_fcp, avg_fcp, slow_fcp), origin, NULL))
93+
)
94+
-
95+
SAFE_DIVIDE(
96+
COUNT(DISTINCT IF(IS_POOR(fast_fcp, avg_fcp, slow_fcp), origin, NULL)),
97+
COUNT(DISTINCT IF(IS_NON_ZERO(fast_fcp, avg_fcp, slow_fcp), origin, NULL)))
98+
AS pct_ni_fcp,
99+
-- Origins with poor FCP divided by origins with any FCP.
100+
SAFE_DIVIDE(
101+
COUNT(DISTINCT IF(IS_POOR(fast_fcp, avg_fcp, slow_fcp), origin, NULL)),
102+
COUNT(DISTINCT IF(IS_NON_ZERO(fast_fcp, avg_fcp, slow_fcp), origin, NULL))
103+
) AS pct_poor_fcp,
104+
105+
-- Origins with good INP divided by origins with any INP.
106+
SAFE_DIVIDE(
107+
COUNT(DISTINCT IF(IS_GOOD(fast_inp, avg_inp, slow_inp), origin, NULL)),
108+
COUNT(DISTINCT IF(IS_NON_ZERO(fast_inp, avg_inp, slow_inp), origin, NULL))
109+
) AS pct_good_inp,
110+
-- Origins with needs improvement are anything not good, nor poor.
111+
1 -
112+
SAFE_DIVIDE(
113+
COUNT(DISTINCT IF(IS_GOOD(fast_inp, avg_inp, slow_inp), origin, NULL)),
114+
COUNT(DISTINCT IF(IS_NON_ZERO(fast_inp, avg_inp, slow_inp), origin, NULL))
115+
)
116+
-
117+
SAFE_DIVIDE(
118+
COUNT(DISTINCT IF(IS_POOR(fast_inp, avg_inp, slow_inp), origin, NULL)),
119+
COUNT(DISTINCT IF(IS_NON_ZERO(fast_inp, avg_inp, slow_inp), origin, NULL)))
120+
AS pct_ni_inp,
121+
-- Origins with poor INP divided by origins with any INP.
122+
SAFE_DIVIDE(
123+
COUNT(DISTINCT IF(IS_POOR(fast_inp, avg_inp, slow_inp), origin, NULL)),
124+
COUNT(DISTINCT IF(IS_NON_ZERO(fast_inp, avg_inp, slow_inp), origin, NULL))
125+
) AS pct_poor_inp,
126+
127+
-- Origins with good CLS divided by origins with any CLS.
128+
SAFE_DIVIDE(
129+
COUNT(DISTINCT IF(IS_GOOD(small_cls, medium_cls, large_cls), origin, NULL)),
130+
COUNT(DISTINCT IF(IS_NON_ZERO(small_cls, medium_cls, large_cls), origin, NULL))
131+
) AS pct_good_cls,
132+
-- Origins with needs improvement are anything not good, nor poor.
133+
1 -
134+
SAFE_DIVIDE(
135+
COUNT(DISTINCT IF(IS_GOOD(small_cls, medium_cls, large_cls), origin, NULL)),
136+
COUNT(DISTINCT IF(IS_NON_ZERO(small_cls, medium_cls, large_cls), origin, NULL))
137+
)
138+
-
139+
SAFE_DIVIDE(
140+
COUNT(DISTINCT IF(IS_POOR(small_cls, medium_cls, large_cls), origin, NULL)),
141+
COUNT(DISTINCT IF(IS_NON_ZERO(small_cls, medium_cls, large_cls), origin, NULL)))
142+
AS pct_ni_cls,
143+
-- Origins with poor CLS divided by origins with any CLS.
144+
SAFE_DIVIDE(
145+
COUNT(DISTINCT IF(IS_POOR(small_cls, medium_cls, large_cls), origin, NULL)),
146+
COUNT(DISTINCT IF(IS_NON_ZERO(small_cls, medium_cls, large_cls), origin, NULL))
147+
) AS pct_poor_cls,
148+
149+
-- Origins with good LCP, INP (optional), and CLS divided by origins with any LCP and CLS.
150+
SAFE_DIVIDE(
151+
COUNT(DISTINCT IF(
152+
IS_GOOD(fast_lcp, avg_lcp, slow_lcp) AND
153+
IS_GOOD(fast_inp, avg_inp, slow_inp) IS NOT FALSE AND
154+
IS_GOOD(small_cls, medium_cls, large_cls), origin, NULL
155+
)),
156+
COUNT(DISTINCT IF(
157+
IS_NON_ZERO(fast_lcp, avg_lcp, slow_lcp) AND
158+
IS_NON_ZERO(small_cls, medium_cls, large_cls), origin, NULL
159+
))
160+
) AS pct_good_cwv
161+
FROM ${ctx.ref('chrome-ux-report', 'materialized', 'device_summary')}
162+
JOIN archive_pages
163+
ON
164+
CONCAT(origin, '/') = url AND
165+
IF(device = 'desktop', 'desktop', 'mobile') = client
166+
JOIN (
167+
-- Add in top theme name for a theme store id AS this should usually be the real theme name
168+
SELECT
169+
COUNT(DISTINCT url) AS pages_count,
170+
theme_store_id,
171+
theme_name,
172+
row_number() OVER (PARTITION BY theme_store_id ORDER BY COUNT(DISTINCT url) DESC) AS rank
173+
FROM archive_pages
174+
GROUP BY
175+
theme_store_id,
176+
theme_name
177+
ORDER BY COUNT(DISTINCT url) DESC
178+
) theme_names
179+
-- Include null theme store ids so that we can get full market share within CrUX
180+
ON IFNULL(theme_names.theme_store_id, 'N/A') = IFNULL(archive_pages.theme_store_id, 'N/A')
181+
WHERE
182+
date = '${pastMonth}' AND
183+
theme_names.rank = 1
184+
GROUP BY
185+
client,
186+
id,
187+
top_theme_name
188+
ORDER BY
189+
origins DESC
190+
`).postOps(ctx => `
191+
SELECT
192+
reports.run_export_job(
193+
JSON '''{
194+
"destination": "storage",
195+
"config": {
196+
"bucket": "${constants.bucket}",
197+
"name": "httparchive/reports/${pastMonth.replaceAll('-', '_')}/cruxShopifyThemes.json"
198+
},
199+
"query": "SELECT * FROM ${ctx.self()}"
200+
}'''
201+
);
202+
`)

0 commit comments

Comments
 (0)