From f4dbc754b6a7bf4ed6b2e3364b5acede419d5699 Mon Sep 17 00:00:00 2001 From: Alexander Karan Date: Wed, 15 Apr 2026 16:05:57 +0800 Subject: [PATCH] Added SPA Charts to other Page --- .../components/SPAStatsMethodologyNotes.astro | 28 ++++++++++++++++ .../docs/src/components/SPAStatsTable.astro | 33 +++++++++++++++++++ packages/docs/src/lib/collections.ts | 17 ++++++++-- .../docs/src/pages/framework/[slug].astro | 30 +++++++++++++++++ packages/docs/src/pages/index.astro | 12 ++----- packages/docs/src/pages/run-time.astro | 7 ++++ 6 files changed, 115 insertions(+), 12 deletions(-) create mode 100644 packages/docs/src/components/SPAStatsMethodologyNotes.astro create mode 100644 packages/docs/src/components/SPAStatsTable.astro diff --git a/packages/docs/src/components/SPAStatsMethodologyNotes.astro b/packages/docs/src/components/SPAStatsMethodologyNotes.astro new file mode 100644 index 00000000..4eaccdaf --- /dev/null +++ b/packages/docs/src/components/SPAStatsMethodologyNotes.astro @@ -0,0 +1,28 @@ +--- +import MethodologyNotes from '../components/MethodologyNotes.astro' +--- + + +
  • Each framework renders a table of 1000 rows with two UUID columns
  • +
  • + Measured using Lighthouse flow with Chromium via Puppeteer for accurate + browser metrics +
  • +
  • + First Paint and First Contentful Paint are measured on initial navigation +
  • +
  • + Interaction to Next Paint is measured by clicking the first row's detail + link +
  • +
  • Benchmarks run 5 times and results are averaged
  • +
  • + Next.js, TanStack Start, and React Router default to SSR with no per-route + opt-out. Next.js wraps the SPA table in a dynamic import with ssr: false to prevent build-time prerendering. TanStack Start uses its built-in spa mode. + React Router disables SSR entirely via ssr: false in its config. + All other frameworks (Nuxt, SvelteKit, SolidStart, Astro) disable SSR per-route + without a separate build. +
  • +
    diff --git a/packages/docs/src/components/SPAStatsTable.astro b/packages/docs/src/components/SPAStatsTable.astro new file mode 100644 index 00000000..46746466 --- /dev/null +++ b/packages/docs/src/components/SPAStatsTable.astro @@ -0,0 +1,33 @@ +--- +import { spaStats } from '../lib/collections' +import { getFrameworkSlug } from '../lib/utils' +import MethodologyTag from './MethodologyTag.astro' +import StatsTable from './StatsTable.astro' + +const columns = [ + { + key: 'name', + header: 'Framework', + nameCell: true, + href: (row: Record) => + row.package !== 'app-baseline-html' + ? `/framework/${getFrameworkSlug(row.package as string)}` + : null, + }, + { key: 'spaFirstPaintMs', header: 'First Paint' }, + { key: 'spaFCPMs', header: 'FCP' }, + { key: 'spaINPMs', header: 'INP' }, +] + +const tableData = spaStats +--- + + + Measured on GitHub Actions (ubuntu-latest, Node 24) using Lighthouse flow with + Chromium. + + diff --git a/packages/docs/src/lib/collections.ts b/packages/docs/src/lib/collections.ts index 7f512f96..ad0cec22 100644 --- a/packages/docs/src/lib/collections.ts +++ b/packages/docs/src/lib/collections.ts @@ -2,7 +2,7 @@ import { getCollection } from 'astro:content' import { formatBytesToMB, formatTimeMs } from './utils' const devtimeEntries = await getCollection('devtime') -const runtimeEntries = await getCollection('runtime') +export const runtimeEntries = await getCollection('runtime') export const starterStats = devtimeEntries .map((entry) => entry.data) @@ -12,6 +12,19 @@ const ssrStats = runtimeEntries .map((entry) => entry.data) .sort((a, b) => a.order - b.order) +const spaStats = runtimeEntries + .map((entry) => entry.data) + .sort((a, b) => a.order - b.order) + .filter((f) => f?.name != null && Number.isFinite(f.spaFirstPaintMs)) + .map((f) => ({ + name: f.name, + package: f.package, + isFocused: f.isFocused, + spaFirstPaintMs: `${f.spaFirstPaintMs}ms`, + spaFCPMs: `${f.spaFCPMs}ms`, + spaINPMs: `${f.spaINPMs}ms`, + })) + const depsStats = starterStats.map((f) => ({ name: f.name, package: f.package, @@ -87,4 +100,4 @@ export const coreJsTableData = starterStats.map((f) => { } }) -export { ssrStats, depsStats, buildInstallData } +export { ssrStats, spaStats, depsStats, buildInstallData } diff --git a/packages/docs/src/pages/framework/[slug].astro b/packages/docs/src/pages/framework/[slug].astro index e7a19df2..0c8f23b0 100644 --- a/packages/docs/src/pages/framework/[slug].astro +++ b/packages/docs/src/pages/framework/[slug].astro @@ -4,6 +4,7 @@ import BackLink from '../../components/BackLink.astro' import DevTimeChart from '../../components/DevTimeChart.astro' import MethodologyTag from '../../components/MethodologyTag.astro' import PageHeader from '../../components/PageHeader.astro' +import SPAStatsMethodologyNotes from '../../components/SPAStatsMethodologyNotes.astro' import SSRStatsMethodologyNotes from '../../components/SSRStatsMethodologyNotes.astro' import StatsTable from '../../components/StatsTable.astro' import Layout from '../../layouts/Layout.astro' @@ -164,6 +165,24 @@ const ssrData = [ ] : []), ] + +const spaColumns = [ + { key: 'name', header: 'Framework', nameCell: true }, + { key: 'spaFirstPaintMs', header: 'First Paint' }, + { key: 'spaFCPMs', header: 'FCP' }, + { key: 'spaINPMs', header: 'INP' }, +] + +const spaData = runtime + ? [ + { + name: runtime.name, + spaFirstPaintMs: `${runtime.spaFirstPaintMs}ms`, + spaFCPMs: `${runtime.spaFCPMs}ms`, + spaINPMs: `${runtime.spaINPMs}ms`, + }, + ] + : [] --- @@ -303,6 +322,17 @@ const ssrData = [ data={ssrData} /> +

    SPA Performance

    + + Measured on GitHub Actions (ubuntu-latest, Node 24) using Lighthouse + flow with Chromium. + + + ) } diff --git a/packages/docs/src/pages/index.astro b/packages/docs/src/pages/index.astro index 1ebd62e5..426b5425 100644 --- a/packages/docs/src/pages/index.astro +++ b/packages/docs/src/pages/index.astro @@ -8,6 +8,7 @@ import DetailsLink from '../components/DetailsLink.astro' import FocusedToggle from '../components/FocusedToggle.astro' import PageHeader from '../components/PageHeader.astro' import SPACharts from '../components/SPACharts.astro' +import SPAStatsTable from '../components/SPAStatsTable.astro' import SSRCharts from '../components/SSRCharts.astro' import SSRStatsTable from '../components/SSRStatsTable.astro' import Layout from '../layouts/Layout.astro' @@ -58,20 +59,11 @@ import Layout from '../layouts/Layout.astro' />

    Runtime Performance

    SSR Performance

    -

    SPA Performance

    -

    - Next.js, TanStack Start, and React Router default to SSR with no per-route - opt-out. Next.js wraps the SPA table in a dynamic import with ssr: false to prevent build-time prerendering. TanStack Start uses its built-in spa mode. - React Router disables SSR entirely via ssr: false in its config. - All other frameworks (Nuxt, SvelteKit, SolidStart, Astro) disable SSR per-route - without a separate build. -

    +