Skip to content

Commit 6189401

Browse files
cwv_by_shopify_theme report (#139)
* cwv_by_shopify_theme * fix configs * cleanup * lint * add contact
1 parent a428173 commit 6189401

1 file changed

Lines changed: 204 additions & 0 deletions

File tree

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

0 commit comments

Comments
 (0)