Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/cwv-stats-monthly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ jobs:
container_id=$(docker run -d cwv-stats)
docker wait "$container_id"
docker cp "$container_id:/app/cwv-stats.json" ./packages/docs/src/content/cwv/cwv-stats.json
cat ./packages/cwv-stats/cwv-stats.json
cat ./packages/docs/src/content/cwv/cwv-stats.json
docker rm "$container_id"

- name: Create Pull Request
Expand All @@ -52,7 +52,7 @@ jobs:

Includes:
- CWV stats for frameworks in packages/cwv-stats/src/frameworks/frameworks.ts
- Outputs stats to packages/cwv-stats/cwv-stats.json
- Outputs stats to packages/docs/src/content/cwv/cwv-stats.json

This PR was automatically created and will auto-merge if all checks pass." \
--base main \
Expand Down
40 changes: 26 additions & 14 deletions packages/cwv-stats/src/cwv/cwv.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
import { type Framework, frameworks } from '../frameworks/frameworks.ts'
import {
type Framework,
type FrameworkName,
type FrameworkPackage,
frameworkMetadata,
frameworks,
} from '../frameworks/frameworks.ts'
import {
type HTTPArchiveCWV,
type HTTPArchiveCWVSnapshot,
Expand All @@ -7,8 +13,9 @@ import {

// httparchive allows us to pull FID but does not include any metrics at this current time so we can ignore it.
type FrameworkCWV = {
id: string
framework: Framework
id: FrameworkPackage
name: FrameworkName
package: FrameworkPackage
date: string
} & {
[cwv in Lowercase<Exclude<HTTPArchiveCWV, 'FID'>>]: {
Expand Down Expand Up @@ -71,17 +78,22 @@ function validateAllCWVIsSameDate(
}

function buildFrameworkCWV(latestFrameworkCWV: HTTPArchiveCWVSnapshot[]) {
const frameworkVitals = latestFrameworkCWV.map((stat) => ({
id: stat.technology.toLowerCase().replace(/[.\s]/g, '-'),
framework: stat.technology,
date: stat.date,
overall: getCWV('overall', stat),
lcp: getCWV('LCP', stat),
cls: getCWV('CLS', stat),
fcp: getCWV('FCP', stat),
ttfb: getCWV('TTFB', stat),
inp: getCWV('INP', stat),
}))
const frameworkVitals = latestFrameworkCWV.map((stat) => {
const framework = frameworkMetadata[stat.technology]

return {
id: framework.package,
name: framework.name,
package: framework.package,
date: stat.date,
overall: getCWV('overall', stat),
lcp: getCWV('LCP', stat),
cls: getCWV('CLS', stat),
fcp: getCWV('FCP', stat),
ttfb: getCWV('TTFB', stat),
inp: getCWV('INP', stat),
}
})

return frameworkVitals
}
Expand Down
15 changes: 15 additions & 0 deletions packages/cwv-stats/src/frameworks/frameworks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,18 @@ export const frameworks = [
] as const

export type Framework = (typeof frameworks)[number]

export const frameworkMetadata = {
'Next.js': { name: 'Next.js', package: 'app-next-js' },
SolidStart: { name: 'SolidStart', package: 'app-solid-start' },
Astro: { name: 'Astro', package: 'app-astro' },
'Nuxt.js': { name: 'Nuxt', package: 'app-nuxt' },
SvelteKit: { name: 'SvelteKit', package: 'app-sveltekit' },
'React Router': { name: 'React Router', package: 'app-react-router' },
} as const satisfies Record<
Framework,
{ name: string; package: `app-${string}` }
>

export type FrameworkName = (typeof frameworkMetadata)[Framework]['name']
export type FrameworkPackage = (typeof frameworkMetadata)[Framework]['package']
4 changes: 2 additions & 2 deletions packages/docs/src/components/CoreWebVitalsTable.astro
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ const { device } = Astro.props

const columns = [
{
key: 'framework',
key: 'name',
header: 'Framework',
nameCell: true,
href: (row: Record<string, unknown>) =>
`/framework/${getFrameworkSlug(row.id as string)}`,
`/framework/${getFrameworkSlug(row.package as string)}`,
},
{ key: 'lcpPercent', header: 'LCP%' },
{ key: 'clsPercent', header: 'CLS%' },
Expand Down
3 changes: 2 additions & 1 deletion packages/docs/src/content.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,8 @@ const cwvCollection = defineCollection({
loader: file('src/content/cwv/cwv-stats.json'),
schema: z.object({
id: z.string(),
framework: z.string(),
name: z.string(),
package: z.string(),
date: z.string(),
overall: z.object({
mobile: z.number(),
Expand Down
32 changes: 19 additions & 13 deletions packages/docs/src/content/cwv/cwv-stats.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
[
{
"id": "sveltekit",
"framework": "SvelteKit",
"id": "app-sveltekit",
"name": "SvelteKit",
"package": "app-sveltekit",
"date": "2026-05-01",
"overall": {
"mobile": 0.5210084033613446,
Expand Down Expand Up @@ -29,8 +30,9 @@
}
},
{
"id": "react-router",
"framework": "React Router",
"id": "app-react-router",
"name": "React Router",
"package": "app-react-router",
"date": "2026-05-01",
"overall": {
"mobile": 0.2791670651238405,
Expand Down Expand Up @@ -58,8 +60,9 @@
}
},
{
"id": "nuxt-js",
"framework": "Nuxt.js",
"id": "app-nuxt",
"name": "Nuxt",
"package": "app-nuxt",
"date": "2026-05-01",
"overall": {
"mobile": 0.28270924275083675,
Expand Down Expand Up @@ -87,8 +90,9 @@
}
},
{
"id": "next-js",
"framework": "Next.js",
"id": "app-next-js",
"name": "Next.js",
"package": "app-next-js",
"date": "2026-05-01",
"overall": {
"mobile": 0.329349427286761,
Expand Down Expand Up @@ -116,8 +120,9 @@
}
},
{
"id": "astro",
"framework": "Astro",
"id": "app-astro",
"name": "Astro",
"package": "app-astro",
"date": "2026-05-01",
"overall": {
"mobile": 0.6768284574468085,
Expand Down Expand Up @@ -145,8 +150,9 @@
}
},
{
"id": "solidstart",
"framework": "SolidStart",
"id": "app-solid-start",
"name": "SolidStart",
"package": "app-solid-start",
"date": "2026-05-01",
"overall": {
"mobile": 0.6363636363636364,
Expand All @@ -173,4 +179,4 @@
"desktop": 1
}
}
]
]
6 changes: 3 additions & 3 deletions packages/docs/src/lib/collections.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ export type Device = 'desktop' | 'mobile'
export const cwvStats = (device: Device) =>
cwvEntries
.map(({ data }) => ({
id: data.id,
framework: data.framework,
name: data.name,
package: data.package,
isFocused: true,
overallPercent: Math.floor(data.overall[device] * 100),
lcpPercent: Math.floor(data.lcp[device] * 100),
Expand All @@ -78,7 +78,7 @@ export function getCWVStatsChartData(cwv: CWV, device: Device) {
return cwvStats(device)
.sort((a, b) => b[`${cwv}Percent`] - a[`${cwv}Percent`])
.map((stat) => ({
name: stat.framework,
name: stat.name,
value: stat[`${cwv}Percent`],
focused: true,
}))
Expand Down
Loading