From 47d67a7348e9a9542d492f6cb2753c7450f8a060 Mon Sep 17 00:00:00 2001 From: Alexander Karan <47707063+AlexanderKaran@users.noreply.github.com> Date: Sun, 19 Jul 2026 16:54:45 +0800 Subject: [PATCH] Added New Detail Page --- .../docs/src/content/docs/framework/astro.md | 7 + .../docs/src/content/docs/framework/mastro.md | 7 + .../src/content/docs/framework/next-js.md | 7 + .../docs/src/content/docs/framework/nuxt.md | 7 + .../content/docs/framework/react-router.md | 7 + .../src/content/docs/framework/solid-start.md | 7 + .../src/content/docs/framework/sveltekit.md | 7 + .../docs/framework/tanstack-start-react.md | 7 + .../docs/src/pages/framework/[slug].astro | 565 ------------------ 9 files changed, 56 insertions(+), 565 deletions(-) create mode 100644 packages/docs/src/content/docs/framework/astro.md create mode 100644 packages/docs/src/content/docs/framework/mastro.md create mode 100644 packages/docs/src/content/docs/framework/next-js.md create mode 100644 packages/docs/src/content/docs/framework/nuxt.md create mode 100644 packages/docs/src/content/docs/framework/react-router.md create mode 100644 packages/docs/src/content/docs/framework/solid-start.md create mode 100644 packages/docs/src/content/docs/framework/sveltekit.md create mode 100644 packages/docs/src/content/docs/framework/tanstack-start-react.md delete mode 100644 packages/docs/src/pages/framework/[slug].astro diff --git a/packages/docs/src/content/docs/framework/astro.md b/packages/docs/src/content/docs/framework/astro.md new file mode 100644 index 00000000..2d2d4511 --- /dev/null +++ b/packages/docs/src/content/docs/framework/astro.md @@ -0,0 +1,7 @@ +--- +title: Astro +description: Astro version comparison page. +--- + +Versioning has not been turned on for Astro yet, so past comparisons are not +active. diff --git a/packages/docs/src/content/docs/framework/mastro.md b/packages/docs/src/content/docs/framework/mastro.md new file mode 100644 index 00000000..63ce8094 --- /dev/null +++ b/packages/docs/src/content/docs/framework/mastro.md @@ -0,0 +1,7 @@ +--- +title: Mastro +description: Mastro version comparison page. +--- + +Versioning has not been turned on for Mastro yet, so past comparisons are not +active. diff --git a/packages/docs/src/content/docs/framework/next-js.md b/packages/docs/src/content/docs/framework/next-js.md new file mode 100644 index 00000000..7a9a7aea --- /dev/null +++ b/packages/docs/src/content/docs/framework/next-js.md @@ -0,0 +1,7 @@ +--- +title: Next.js +description: Next.js version comparison page. +--- + +Versioning has not been turned on for Next.js yet, so past comparisons are not +active. diff --git a/packages/docs/src/content/docs/framework/nuxt.md b/packages/docs/src/content/docs/framework/nuxt.md new file mode 100644 index 00000000..ec717435 --- /dev/null +++ b/packages/docs/src/content/docs/framework/nuxt.md @@ -0,0 +1,7 @@ +--- +title: Nuxt +description: Nuxt version comparison page. +--- + +Versioning has not been turned on for Nuxt yet, so past comparisons are not +active. diff --git a/packages/docs/src/content/docs/framework/react-router.md b/packages/docs/src/content/docs/framework/react-router.md new file mode 100644 index 00000000..5e70b2ac --- /dev/null +++ b/packages/docs/src/content/docs/framework/react-router.md @@ -0,0 +1,7 @@ +--- +title: React Router +description: React Router version comparison page. +--- + +Versioning has not been turned on for React Router yet, so past comparisons are +not active. diff --git a/packages/docs/src/content/docs/framework/solid-start.md b/packages/docs/src/content/docs/framework/solid-start.md new file mode 100644 index 00000000..a6c91027 --- /dev/null +++ b/packages/docs/src/content/docs/framework/solid-start.md @@ -0,0 +1,7 @@ +--- +title: SolidStart +description: SolidStart version comparison page. +--- + +Versioning has not been turned on for SolidStart yet, so past comparisons are +not active. diff --git a/packages/docs/src/content/docs/framework/sveltekit.md b/packages/docs/src/content/docs/framework/sveltekit.md new file mode 100644 index 00000000..b91b8c66 --- /dev/null +++ b/packages/docs/src/content/docs/framework/sveltekit.md @@ -0,0 +1,7 @@ +--- +title: SvelteKit +description: SvelteKit version comparison page. +--- + +Versioning has not been turned on for SvelteKit yet, so past comparisons are +not active. diff --git a/packages/docs/src/content/docs/framework/tanstack-start-react.md b/packages/docs/src/content/docs/framework/tanstack-start-react.md new file mode 100644 index 00000000..2f40bfe3 --- /dev/null +++ b/packages/docs/src/content/docs/framework/tanstack-start-react.md @@ -0,0 +1,7 @@ +--- +title: TanStack Start +description: TanStack Start version comparison page. +--- + +Versioning has not been turned on for TanStack Start yet, so past comparisons +are not active. diff --git a/packages/docs/src/pages/framework/[slug].astro b/packages/docs/src/pages/framework/[slug].astro deleted file mode 100644 index 0008db44..00000000 --- a/packages/docs/src/pages/framework/[slug].astro +++ /dev/null @@ -1,565 +0,0 @@ ---- -import { getCollection } from 'astro:content' -import BrowserBaselineTable from '../../components/BrowserBaselineTable.astro' -import DevTimeChart from '../../components/DevTimeChart.astro' -import StatsTable from '../../components/StatsTable.astro' -import StarlightPage from '@astrojs/starlight/components/StarlightPage.astro' -import { - buildInstallData, - depsStats, - ssrLoadStats, -} from '../../lib/collections' -import { getFrameworkSlug } from '../../lib/utils' - -export async function getStaticPaths() { - const devtimeEntries = await getCollection('devtime') - const runtimeEntries = await getCollection('runtime') - const baseline = runtimeEntries.find( - (e) => e.data.package === 'app-baseline-html', - )?.data - return devtimeEntries.map((entry) => { - const slug = getFrameworkSlug(entry.data.package) - const runtimePackage = `app-${slug}` - const runtimeEntry = runtimeEntries.find( - (e) => e.data.package === runtimePackage, - ) - return { - params: { slug }, - props: { - devtime: entry.data, - runtime: runtimeEntry?.data, - baseline, - e18eMessages: entry.data.e18eMessages ?? [], - }, - } - }) -} - -const { devtime, runtime, baseline, e18eMessages } = Astro.props - -const duplicateDependencyMessages = e18eMessages.filter((m) => - m.message.startsWith('[duplicate dependency]'), -) - -const coreJsModules = devtime.vendoredCoreJsUnnecessaryModules ?? [] -const coreJsGroups = coreJsModules.reduce>( - (acc, mod) => { - const parts = mod.split('.') - const group = parts[0] === 'web' ? 'web' : `${parts[0]}.${parts[1]}` - acc[group] = (acc[group] ?? 0) + 1 - return acc - }, - {}, -) -const coreJsGroupEntries = Object.entries(coreJsGroups).sort( - (a, b) => b[1] - a[1], -) -const coreJsSizeKb = - devtime.vendoredCoreJsSize != null && devtime.vendoredCoreJsSize > 0 - ? (devtime.vendoredCoreJsSize / 1024).toFixed(1) - : null - -function parseDupeName(message: string): string { - const match = message.match(/\[duplicate dependency\] (\S+) has/) - return match?.[1] ?? 'unknown' -} - -const measuredDateDisplay = (() => { - const d = new Date(devtime.timingMeasuredAt) - return Number.isNaN(d.getTime()) - ? devtime.timingMeasuredAt - : d.toLocaleDateString('en-US') -})() - -const depsEntry = depsStats.find((e) => e.package === devtime.package)! -const buildEntry = buildInstallData.find((e) => e.package === devtime.package)! - -const depsColumns = [ - { key: 'directDependencies', header: 'Deps Dev / Prod' }, - { key: 'allDependencies', header: 'All Deps' }, - ...(devtime.duplicateDependencies != null - ? [{ key: 'duplicateDependencies', header: 'Dup. Deps' }] - : []), - { key: 'nodeModulesSize', header: 'node_modules' }, - { key: 'nodeModulesSizeProdOnly', header: 'node_modules (prod)' }, - { key: 'depInstallSize', header: 'Dep Install Size' }, - { - key: 'graph', - header: 'Graph', - href: (row: Record) => row.graphHref as string, - }, -] - -const depsData = [ - { - directDependencies: depsEntry.directDependencies, - allDependencies: depsEntry.allDependencies, - ...(devtime.duplicateDependencies != null - ? { duplicateDependencies: String(devtime.duplicateDependencies) } - : {}), - nodeModulesSize: depsEntry.nodeModulesSize, - nodeModulesSizeProdOnly: depsEntry.nodeModulesSizeProdOnly, - depInstallSize: depsEntry.depInstallSize, - graph: depsEntry.graph, - graphHref: `https://npmgraph.js.org/?q=https://github.com/e18e/framework-tracker/blob/main/packages/${devtime.package}/package.json`, - }, -] - -const buildColumns = [ - { key: 'metric', header: 'Metric', nameCell: true }, - { key: 'avg', header: 'Avg' }, - { key: 'min', header: 'Min' }, - { key: 'max', header: 'Max' }, -] - -const buildData = [ - { - metric: 'Install', - avg: buildEntry.avgInstall, - min: buildEntry.minInstall, - max: buildEntry.maxInstall, - }, - { - metric: 'Cold Build', - avg: buildEntry.avgColdBuild, - min: buildEntry.minColdBuild, - max: buildEntry.maxColdBuild, - }, - { - metric: 'Warm Build', - avg: buildEntry.avgWarmBuild, - min: buildEntry.minWarmBuild, - max: buildEntry.maxWarmBuild, - }, -] - -const ssrRequestThroughputColumns = [ - { key: 'name', header: 'Framework', nameCell: true }, - { key: 'opsPerSec', header: 'Ops/sec' }, - { key: 'medianLatencyMs', header: 'Median Latency' }, - { key: 'bodySizeKb', header: 'Body Size' }, - { key: 'duplicationFactor', header: 'Duplication' }, -] - -const ssrRequestThroughputData = [ - ...(baseline - ? [ - { - name: baseline.name, - opsPerSec: - baseline.ssrRequestThroughputTests.opsPerSec.toLocaleString(), - medianLatencyMs: `${baseline.ssrRequestThroughputTests.medianLatencyMs}ms`, - bodySizeKb: `${baseline.ssrRequestThroughputTests.bodySizeKb}kb`, - duplicationFactor: `${baseline.ssrRequestThroughputTests.duplicationFactor}x`, - }, - ] - : []), - ...(runtime - ? [ - { - name: runtime.name, - opsPerSec: - runtime.ssrRequestThroughputTests.opsPerSec.toLocaleString(), - medianLatencyMs: `${runtime.ssrRequestThroughputTests.medianLatencyMs}ms`, - bodySizeKb: `${runtime.ssrRequestThroughputTests.bodySizeKb}kb`, - duplicationFactor: `${runtime.ssrRequestThroughputTests.duplicationFactor}x`, - }, - ] - : []), -] - -const ssrLoadColumns = [ - { key: 'name', header: 'Framework', nameCell: true }, - { key: 'peakRequestsPerSec', header: 'Peak req/s' }, - { key: 'peakWorkers', header: 'Peak Connections' }, - { key: 'worker25P99LatencyMs', header: 'P99 @ 25' }, - { key: 'worker50P99LatencyMs', header: 'P99 @ 50' }, - { key: 'worker100P99LatencyMs', header: 'P99 @ 100' }, - { key: 'totalRequests', header: 'Total Req.' }, -] - -const ssrLoadData = [ - ...ssrLoadStats.filter((entry) => entry.package === 'app-baseline-html'), - ...ssrLoadStats.filter( - (entry) => runtime && entry.package === runtime.package, - ), -] - -const clientSideRenderedColumns = [ - { key: 'name', header: 'Framework', nameCell: true }, - { key: 'firstPaintMs', header: 'First Paint' }, - { key: 'fcpMs', header: 'FCP' }, - { key: 'inpMs', header: 'INP' }, -] - -const clientSideRenderedData = runtime?.clientSideRenderedTests - ? [ - { - name: runtime.name, - firstPaintMs: `${runtime.clientSideRenderedTests.firstPaintMs}ms`, - fcpMs: `${runtime.clientSideRenderedTests.fcpMs}ms`, - inpMs: `${runtime.clientSideRenderedTests.inpMs}ms`, - }, - ] - : [] - -const serverSideRenderedColumns = [ - { key: 'name', header: 'Framework', nameCell: true }, - { key: 'firstPaintMs', header: 'First Paint' }, - { key: 'fcpMs', header: 'FCP' }, - { key: 'inpMs', header: 'INP' }, -] - -const serverSideRenderedData = runtime?.serverSideRenderedTests - ? [ - { - name: runtime.name, - firstPaintMs: `${runtime.serverSideRenderedTests.firstPaintMs}ms`, - fcpMs: `${runtime.serverSideRenderedTests.fcpMs}ms`, - inpMs: `${runtime.serverSideRenderedTests.inpMs}ms`, - }, - ] - : [] ---- - - -
- { - (devtime.frameworkVersion ?? devtime.timingMeasuredAt) && ( -

- {devtime.frameworkVersion && ( - Version {devtime.frameworkVersion} - )} - {devtime.frameworkVersion && devtime.timingMeasuredAt && ' · '} - {devtime.timingMeasuredAt && ( - Measured {measuredDateDisplay} - )} -

- ) - } -
- -

Dev Time Performance

- -

- Methodology: - Dependency Counts and - Node Modules Size. -

- - -

- Build output size: - {buildEntry.buildOutput} -

-

- Methodology: Build and Install Times. -

-

Browser Baseline

- -

- Methodology: Browser Baseline. -

- - { - coreJsModules.length > 0 && ( -
-

Unnecessary Core-JS Polyfills

-

- {coreJsModules.length}{' '} - - core-js - {' '} - polyfill module{coreJsModules.length === 1 ? '' : 's'} are bundled but - already natively supported by the{' '} - - last 2 major versions of Chrome, Firefox, Safari, and Edge - {' '} - — code users download even though their browser already supports it - natively. - {coreJsSizeKb && ( - <> - {' '} - The containing chunk is approximately{' '} - {coreJsSizeKb} KB (chunk size, not isolated - core-js bytes). - - )} -

-

- Methodology:{' '} - Core-JS Polyfills. -

-
- - View {coreJsModules.length} unnecessary{' '} - {coreJsModules.length === 1 ? 'module' : 'modules'} by category - -
    - {coreJsGroupEntries.map(([group, count]) => ( -
  • - {group}.* - {count} -
  • - ))} -
-
-
- ) - } - - { - duplicateDependencyMessages.length > 0 && ( -
-

Duplicate Dependencies

-

- {duplicateDependencyMessages.length} duplicate{' '} - {duplicateDependencyMessages.length === 1 - ? 'dependency' - : 'dependencies'}{' '} - detected across this starter's node_modules. -

-

- Methodology:{' '} - - Duplicate Dependencies - - . -

-
- - View {duplicateDependencyMessages.length} duplicate{' '} - {duplicateDependencyMessages.length === 1 - ? 'dependency' - : 'dependencies'} - -
    - {duplicateDependencyMessages.map((msg) => ( -
  • - {parseDupeName(msg.message)} -
    {msg.message}
    -
  • - ))} -
-
-
- ) - } - - { - runtime && ( - <> -

Runtime Performance

-

Client Side Rendered Tests

-

- Methodology:{' '} - - Client Side Rendered Tests - - . -

- -

Server Side Rendered Tests

-

- Methodology:{' '} - - Server Side Rendered Tests - - . -

- -

Server Side Throughput Tests

-

- Methodology:{' '} - - Server Side Throughput Tests - - . -

- -

Server Side Load Test

-

- Methodology:{' '} - Server Side Load Test - . -

- - - ) - } -
- -