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
48 changes: 48 additions & 0 deletions .github/workflows/benchmarks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
name: Benchmarks

on:
push:
branches: [main]
paths:
- 'packages/starlight/**'
- '!packages/starlight/__tests__/**'
- '!packages/starlight/__e2e__/**'
- 'package.json'
- 'pnpm-lock.yaml'
- 'pnpm-workspace.yaml'
- '.github/workflows/benchmarks.yml'
pull_request:
branches: [main]
paths:
- 'packages/starlight/**'
- '!packages/starlight/__tests__/**'
- '!packages/starlight/__e2e__/**'
- 'package.json'
- 'pnpm-lock.yaml'
- 'pnpm-workspace.yaml'
- '.github/workflows/benchmarks.yml'
workflow_dispatch:

concurrency:
group: codspeed-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

jobs:
benchmarks:
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: 22.23.1
cache: pnpm
- run: pnpm i --filter @astrojs/starlight
- name: Run benchmarks
uses: CodSpeedHQ/action@4296e51e7041e24dadb86d1d6e8b9320d223dbe8 # v5.0.3
with:
mode: simulation
run: pnpm --filter @astrojs/starlight bench
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,5 @@ test-results/

# Vercel output
.vercel

.idea
Comment thread
delucis marked this conversation as resolved.
1 change: 1 addition & 0 deletions packages/starlight/.npmignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
__coverage__/
__tests__/
__e2e__/
__bench_fn__/
vitest.*
playwright.config.ts
# Astro generates this during tests, but we want to ignore it.
Expand Down
50 changes: 50 additions & 0 deletions packages/starlight/__bench_fn__/generate-route-data.bench.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { bench, describe, vi } from 'vitest';
import { getRouteDataTestContext } from '../__tests__/test-utils';
import { generateRouteData } from '../utils/routing/data';
import { getRouteBySlugParam } from '../utils/routing';
import { getSidebar } from '../utils/navigation';

const docs = vi.hoisted(() => {
const docs: [string, { title: string }][] = [];
for (let section = 0; section < 10; section++) {
const nesting = Array.from({ length: 7 }, (_, index) => `level-${index + 1}`).join('/');
for (let page = 0; page < 100; page++) {
docs.push([
`reference/section-${section}/${nesting}/page-${page}.md`,
{ title: `Page ${section}-${page}` },
]);
}
}
return docs;
});

vi.mock('astro:content', async () =>
(await import('../__tests__/test-utils')).mockedAstroContent({ docs })
);

const slug = 'reference/section-9/level-1/level-2/level-3/level-4/level-5/level-6/level-7/page-99';
const route = getRouteBySlugParam(slug);
if (!route) throw new Error('Expected deep benchmark route to exist.');

const context = getRouteDataTestContext({ pathname: `/${slug}/` });
const props = {
...route,
headings: Array.from({ length: 30 }, (_, index) => ({
depth: 2,
slug: `heading-${index}`,
text: `Heading ${index}`,
})),
};

// Build intermediate sidebar data once so this models subsequent page generation during a build.
getSidebar(context.url.pathname, route.locale);

describe('routing', () => {
bench('route_data', () => {
generateRouteData({ props, context });
});

bench('sidebar', () => {
getSidebar(context.url.pathname, route.locale);
});
});
3 changes: 3 additions & 0 deletions packages/starlight/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
"scripts": {
"test": "VITE_CONFIG_NATIVE_IGNORE_WARNING=true vitest",
"test:coverage": "VITE_CONFIG_NATIVE_IGNORE_WARNING=true vitest run --coverage",
"bench": "pnpm bench:functional",
"bench:functional": "VITE_CONFIG_NATIVE_IGNORE_WARNING=true vitest bench --run --config vitest.functional.bench.config.ts __bench_fn__/*.bench.ts",
"test:e2e": "playwright install --with-deps chromium && playwright test",
"test:e2e:ci": "playwright test"
},
Expand Down Expand Up @@ -59,6 +61,7 @@
"devDependencies": {
"@astrojs/markdown-remark": "^7.2.2",
"@playwright/test": "^1.61.1",
"@codspeed/vitest-plugin": "^5.7.1",
"@types/node": "^22.19.17",
"@vitest/coverage-v8": "^4.1.5",
"astro": "^7.1.6",
Expand Down
24 changes: 24 additions & 0 deletions packages/starlight/vitest.functional.bench.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import codspeedPlugin from '@codspeed/vitest-plugin';
import { defineVitestConfig } from './__tests__/test-config';

const testConfig = await defineVitestConfig({
title: 'Starlight benchmarks',
sidebar: [{ label: 'Reference', items: [{ autogenerate: { directory: 'reference' } }] }],
});

export default async (env: Parameters<typeof testConfig>[0]) => {
const config = await testConfig(env);
return {
...config,
plugins: [...(config.plugins ?? []), codspeedPlugin()],
test: {
...config.test,
// The shared serializer path is not resolvable from this root benchmark config.
snapshotSerializers: [],
benchmark: {
include: ['__bench_fn__/*.bench.ts'],
},
fileParallelism: false,
},
};
};
Loading
Loading