Skip to content

Commit f98fd20

Browse files
authored
CWV Stats for Mobile (#282)
1 parent a50b0f2 commit f98fd20

6 files changed

Lines changed: 73 additions & 51 deletions

File tree

packages/docs/src/components/CoreWebVitalChart.astro

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
---
2-
import { getCWVDesktopStatsChartData } from '../lib/collections'
3-
import type { CWV } from '../lib/collections'
2+
import { getCWVStatsChartData } from '../lib/collections'
3+
import type { CWV, Device } from '../lib/collections'
44
import ComparisonBarChart from './ComparisonBarChart.astro'
55
66
interface Props {
77
cwv: CWV
8+
device: Device
89
}
910
10-
const { cwv } = Astro.props
11+
const { cwv, device } = Astro.props
1112
1213
const cwvTitle: Record<CWV, string> = {
1314
lcp: 'Good Largest Contentful Paint',
@@ -29,7 +30,7 @@ const cwvDescription: Record<CWV, string> = {
2930
<ComparisonBarChart
3031
title={cwvTitle[cwv]}
3132
description={cwvDescription[cwv]}
32-
data={getCWVDesktopStatsChartData(cwv)}
33+
data={getCWVStatsChartData(cwv, device)}
3334
valueFormat="count"
3435
yAxisLabel="%"
3536
/>
Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,32 @@
11
---
22
import ChartTabs from './ChartTabs.astro'
33
import CoreWebVitalChart from './CoreWebVitalChart.astro'
4+
import type { Device } from '../lib/collections'
5+
6+
interface Props {
7+
device: Device
8+
}
9+
10+
const { device } = Astro.props
11+
12+
const deviceLabel: Record<Device, string> = {
13+
desktop: 'Core Web Vitals Desktop',
14+
mobile: 'Core Web Vitals Mobile',
15+
}
416
---
517

618
<ChartTabs
7-
sectionId="client-side-rendered"
8-
label="Core Web Vitals Desktop"
19+
sectionId="core-web-vitals"
20+
label={deviceLabel[device]}
921
tab1Label="LCP"
1022
tab2Label="CLS"
1123
tab3Label="FCP"
1224
tab4Label="TTFB"
1325
tab5Label="INP"
1426
>
15-
<CoreWebVitalChart slot="panel-1" cwv="lcp" />
16-
<CoreWebVitalChart slot="panel-2" cwv="cls" />
17-
<CoreWebVitalChart slot="panel-3" cwv="fcp" />
18-
<CoreWebVitalChart slot="panel-4" cwv="ttfb" />
19-
<CoreWebVitalChart slot="panel-5" cwv="inp" />
27+
<CoreWebVitalChart slot="panel-1" cwv="lcp" device={device} />
28+
<CoreWebVitalChart slot="panel-2" cwv="cls" device={device} />
29+
<CoreWebVitalChart slot="panel-3" cwv="fcp" device={device} />
30+
<CoreWebVitalChart slot="panel-4" cwv="ttfb" device={device} />
31+
<CoreWebVitalChart slot="panel-5" cwv="inp" device={device} />
2032
</ChartTabs>

packages/docs/src/components/CoreWebVitalsTable.astro

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,13 @@
22
import { cwvStats } from '../lib/collections'
33
import { getFrameworkSlug } from '../lib/utils'
44
import StatsTable from './StatsTable.astro'
5+
import type { Device } from '../lib/collections'
6+
7+
interface Props {
8+
device: Device
9+
}
10+
11+
const { device } = Astro.props
512
613
const columns = [
714
{
@@ -11,12 +18,16 @@ const columns = [
1118
href: (row: Record<string, unknown>) =>
1219
`/framework/${getFrameworkSlug(row.id as string)}`,
1320
},
14-
{ key: 'lcpDesktopPercent', header: 'LCP%' },
15-
{ key: 'clsDesktopPercent', header: 'CLS%' },
16-
{ key: 'fcpDesktopPercent', header: 'FCP%' },
17-
{ key: 'ttfbDesktopPercent', header: 'TTFB%' },
18-
{ key: 'inpDesktopPercent', header: 'INP%' },
21+
{ key: 'lcpPercent', header: 'LCP%' },
22+
{ key: 'clsPercent', header: 'CLS%' },
23+
{ key: 'fcpPercent', header: 'FCP%' },
24+
{ key: 'ttfbPercent', header: 'TTFB%' },
25+
{ key: 'inpPercent', header: 'INP%' },
1926
]
2027
---
2128

22-
<StatsTable label="CWV by framework" columns={columns} data={cwvStats} />
29+
<StatsTable
30+
label="CWV by framework"
31+
columns={columns}
32+
data={cwvStats(device)}
33+
/>

packages/docs/src/lib/collections.ts

Lines changed: 20 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5,33 +5,31 @@ const devtimeEntries = await getCollection('devtime')
55
export const runtimeEntries = await getCollection('runtime')
66
const cwvEntries = await getCollection('cwv')
77

8-
export const cwvStats = cwvEntries
9-
.map((entry) => entry.data)
10-
.sort((a, b) => b.overall.desktop - a.overall.desktop)
11-
.map((stat) => ({
12-
id: stat.id,
13-
framework: stat.framework,
14-
isFocused: true,
15-
lcpDesktopPercent: Math.floor(stat.lcp.desktop * 100),
16-
lcpMobilePercent: Math.floor(stat.lcp.mobile * 100),
17-
clsDesktopPercent: Math.floor(stat.cls.desktop * 100),
18-
clsMobilePercent: Math.floor(stat.cls.mobile * 100),
19-
fcpDesktopPercent: Math.floor(stat.fcp.desktop * 100),
20-
fcpMobilePercent: Math.floor(stat.fcp.mobile * 100),
21-
ttfbDesktopPercent: Math.floor(stat.ttfb.desktop * 100),
22-
ttfbMobilePercent: Math.floor(stat.ttfb.mobile * 100),
23-
inpDesktopPercent: Math.floor(stat.inp.desktop * 100),
24-
inpMobilePercent: Math.floor(stat.inp.mobile * 100),
25-
}))
8+
export type Device = 'desktop' | 'mobile'
9+
10+
export const cwvStats = (device: Device) =>
11+
cwvEntries
12+
.map(({ data }) => ({
13+
id: data.id,
14+
framework: data.framework,
15+
isFocused: true,
16+
overallPercent: Math.floor(data.overall[device] * 100),
17+
lcpPercent: Math.floor(data.lcp[device] * 100),
18+
clsPercent: Math.floor(data.cls[device] * 100),
19+
fcpPercent: Math.floor(data.fcp[device] * 100),
20+
ttfbPercent: Math.floor(data.ttfb[device] * 100),
21+
inpPercent: Math.floor(data.inp[device] * 100),
22+
}))
23+
.sort((a, b) => b.overallPercent - a.overallPercent)
2624

2725
export type CWV = 'lcp' | 'cls' | 'fcp' | 'ttfb' | 'inp'
2826

29-
export function getCWVDesktopStatsChartData(cwv: CWV) {
30-
return cwvStats
31-
.sort((a, b) => b[`${cwv}DesktopPercent`] - a[`${cwv}DesktopPercent`])
27+
export function getCWVStatsChartData(cwv: CWV, device: Device) {
28+
return cwvStats(device)
29+
.sort((a, b) => b[`${cwv}Percent`] - a[`${cwv}Percent`])
3230
.map((stat) => ({
3331
name: stat.framework,
34-
value: stat[`${cwv}DesktopPercent`],
32+
value: stat[`${cwv}Percent`],
3533
focused: true,
3634
}))
3735
}

packages/docs/src/pages/methodology.astro

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -304,19 +304,19 @@ import Layout from '../layouts/Layout.astro'
304304
</ul>
305305
</section>
306306

307-
<section id="core-web-vitals-desktop">
308-
<h3>Core Web Vitals Desktop</h3>
307+
<section id="core-web-vitals">
308+
<h3>Core Web Vitals</h3>
309309
<ul>
310310
<li>
311-
Core Web Vitals desktop metrics are sourced from <a
311+
Core Web Vital metrics are sourced from <a
312312
href="https://httparchive.org/reports/techreport/tech"
313313
target="_blank"
314314
rel="noopener noreferrer">HTTP Archive</a
315315
> technology reports.
316316
</li>
317317
<li>
318-
The docs publish framework-level desktop percentages from the latest
319-
collected HTTP Archive snapshot in the repository.
318+
The docs publish framework-level desktop and mobile percentages from the
319+
latest collected HTTP Archive snapshot in the repository.
320320
</li>
321321
<li>Metrics refresh monthly when new HTTP Archive data is collected.</li>
322322
</ul>

packages/docs/src/pages/run-time.astro

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,11 @@ import DetailsLink from '../components/DetailsLink.astro'
4848
<h3>P90 Latency</h3>
4949
<SSRLoadP90Charts />
5050
<SSRLoadStatsTable />
51-
<h2 id="core-web-vitals-desktop">Core Web Vitals Desktop</h2>
52-
<DetailsLink
53-
href="/methodology#core-web-vitals-desktop"
54-
label="Core Web Vitals Desktop"
55-
/>
56-
<CoreWebVitalsCharts />
57-
<CoreWebVitalsTable />
51+
<h3>CWV Desktop</h3>
52+
<CoreWebVitalsCharts device="desktop" />
53+
<CoreWebVitalsTable device="desktop" />
54+
<h3>CWV Mobile</h3>
55+
<CoreWebVitalsCharts device="mobile" />
56+
<CoreWebVitalsTable device="mobile" />
57+
<DetailsLink href="/methodology#core-web-vitals" label="Core Web Vitals" />
5858
</Layout>

0 commit comments

Comments
 (0)