mirror of
https://github.com/withastro/astro.git
synced 2024-12-30 22:03:56 -05:00
chore: codspeed benchmark (#12347)
This commit is contained in:
parent
222f71894c
commit
ed5a9f1b75
19 changed files with 527 additions and 42 deletions
50
.github/workflows/continuous_benchmark.yml
vendored
Normal file
50
.github/workflows/continuous_benchmark.yml
vendored
Normal file
|
@ -0,0 +1,50 @@
|
|||
name: Continuous benchmark
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
|
||||
env:
|
||||
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
|
||||
TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
|
||||
FORCE_COLOR: true
|
||||
CODSPEED_TOKEN: ${{ secrets.CODSPEED_TOKEN }}
|
||||
CODSPEED: true
|
||||
|
||||
jobs:
|
||||
codspeed:
|
||||
if: ${{ github.repository_owner == 'withastro' }}
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
steps:
|
||||
- name: Check out repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup PNPM
|
||||
uses: pnpm/action-setup@v3
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 18
|
||||
cache: "pnpm"
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install
|
||||
|
||||
- name: Build
|
||||
run: pnpm run build
|
||||
|
||||
- name: Run the benchmarks
|
||||
uses: CodSpeedHQ/action@b587655f756aab640e742fec141261bc6f0a569d # v3.0.1
|
||||
timeout-minutes: 30
|
||||
with:
|
||||
run: pnpm benchmark codspeed
|
||||
|
|
@ -14,7 +14,7 @@ export const astroBin = path.resolve(astroPkgPath, '../astro.js');
|
|||
export function calculateStat(numbers) {
|
||||
const avg = numbers.reduce((a, b) => a + b, 0) / numbers.length;
|
||||
const stdev = Math.sqrt(
|
||||
numbers.map((x) => Math.pow(x - avg, 2)).reduce((a, b) => a + b, 0) / numbers.length
|
||||
numbers.map((x) => Math.pow(x - avg, 2)).reduce((a, b) => a + b, 0) / numbers.length,
|
||||
);
|
||||
const max = Math.max(...numbers);
|
||||
return { avg, stdev, max };
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { fileURLToPath } from 'node:url';
|
||||
import { exec } from 'tinyexec';
|
||||
import { markdownTable } from 'markdown-table';
|
||||
import { exec } from 'tinyexec';
|
||||
import { astroBin, calculateStat } from './_util.js';
|
||||
|
||||
/** Default project to run for this benchmark if not specified */
|
||||
|
@ -8,9 +8,8 @@ export const defaultProject = 'render-default';
|
|||
|
||||
/**
|
||||
* @param {URL} projectDir
|
||||
* @param {URL} outputFile
|
||||
*/
|
||||
export async function run(projectDir, outputFile) {
|
||||
export async function run(projectDir) {
|
||||
const root = fileURLToPath(projectDir);
|
||||
|
||||
console.log('Benchmarking `astro --help`...');
|
||||
|
@ -28,7 +27,7 @@ export async function run(projectDir, outputFile) {
|
|||
printResult({
|
||||
'astro --help': helpStat,
|
||||
'astro info': infoStat,
|
||||
})
|
||||
}),
|
||||
);
|
||||
console.log('='.repeat(10));
|
||||
}
|
||||
|
@ -69,6 +68,6 @@ function printResult(result) {
|
|||
],
|
||||
{
|
||||
align: ['l', 'r', 'r', 'r'],
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
|
50
benchmark/bench/codspeed.js
Normal file
50
benchmark/bench/codspeed.js
Normal file
|
@ -0,0 +1,50 @@
|
|||
import path from 'node:path';
|
||||
import { withCodSpeed } from '@codspeed/tinybench-plugin';
|
||||
import { Bench } from 'tinybench';
|
||||
import { exec } from 'tinyexec';
|
||||
import { renderPages } from '../make-project/render-default.js';
|
||||
import { astroBin } from './_util.js';
|
||||
|
||||
export async function run({ memory: _memory, render, stress: _stress }) {
|
||||
const options = {
|
||||
iterations: 10,
|
||||
};
|
||||
const bench = process.env.CODSPEED ? withCodSpeed(new Bench(options)) : new Bench(options);
|
||||
let app;
|
||||
bench.add(
|
||||
'Rendering',
|
||||
async () => {
|
||||
console.info('Start task.');
|
||||
const result = {};
|
||||
for (const fileName of renderPages) {
|
||||
const pathname = '/' + fileName.slice(0, -path.extname(fileName).length);
|
||||
const request = new Request(new URL(pathname, 'http://exmpale.com'));
|
||||
const response = await app.render(request);
|
||||
const html = await response.text();
|
||||
if (!result[pathname]) result[pathname] = [];
|
||||
result[pathname].push(html);
|
||||
}
|
||||
console.info('Finish task.');
|
||||
return result;
|
||||
},
|
||||
{
|
||||
async beforeAll() {
|
||||
// build for rendering
|
||||
await exec(astroBin, ['build'], {
|
||||
nodeOptions: {
|
||||
cwd: render.root,
|
||||
stdio: 'inherit',
|
||||
},
|
||||
});
|
||||
|
||||
const entry = new URL('./dist/server/entry.mjs', `file://${render.root}`);
|
||||
const { manifest, createApp } = await import(entry);
|
||||
app = createApp(manifest);
|
||||
app.manifest = manifest;
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
await bench.run();
|
||||
console.table(bench.table());
|
||||
}
|
|
@ -56,6 +56,6 @@ function printResult(output) {
|
|||
],
|
||||
{
|
||||
align: ['l', 'r', 'r', 'r'],
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
import { exec } from 'tinyexec';
|
||||
import { markdownTable } from 'markdown-table';
|
||||
import fs from 'node:fs/promises';
|
||||
import http from 'node:http';
|
||||
import path from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { markdownTable } from 'markdown-table';
|
||||
import { waitUntilBusy } from 'port-authority';
|
||||
import { calculateStat, astroBin } from './_util.js';
|
||||
import { exec } from 'tinyexec';
|
||||
import { renderPages } from '../make-project/render-default.js';
|
||||
import { astroBin, calculateStat } from './_util.js';
|
||||
|
||||
const port = 4322;
|
||||
|
||||
|
@ -60,14 +60,14 @@ export async function run(projectDir, outputFile) {
|
|||
console.log('Done!');
|
||||
}
|
||||
|
||||
async function benchmarkRenderTime() {
|
||||
export async function benchmarkRenderTime(portToListen = port) {
|
||||
/** @type {Record<string, number[]>} */
|
||||
const result = {};
|
||||
for (const fileName of renderPages) {
|
||||
// Render each file 100 times and push to an array
|
||||
for (let i = 0; i < 100; i++) {
|
||||
const pathname = '/' + fileName.slice(0, -path.extname(fileName).length);
|
||||
const renderTime = await fetchRenderTime(`http://localhost:${port}${pathname}`);
|
||||
const renderTime = await fetchRenderTime(`http://localhost:${portToListen}${pathname}`);
|
||||
if (!result[pathname]) result[pathname] = [];
|
||||
result[pathname].push(renderTime);
|
||||
}
|
||||
|
@ -97,7 +97,7 @@ function printResult(result) {
|
|||
],
|
||||
{
|
||||
align: ['l', 'r', 'r', 'r'],
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import autocannon from 'autocannon';
|
||||
import { exec } from 'tinyexec';
|
||||
import { markdownTable } from 'markdown-table';
|
||||
import fs from 'node:fs/promises';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import autocannon from 'autocannon';
|
||||
import { markdownTable } from 'markdown-table';
|
||||
import { waitUntilBusy } from 'port-authority';
|
||||
import pb from 'pretty-bytes';
|
||||
import { exec } from 'tinyexec';
|
||||
import { astroBin } from './_util.js';
|
||||
|
||||
const port = 4321;
|
||||
|
@ -28,9 +28,11 @@ export async function run(projectDir, outputFile) {
|
|||
});
|
||||
|
||||
console.log('Previewing...');
|
||||
const previewProcess = execaCommand(`${astroBin} preview --port ${port}`, {
|
||||
cwd: root,
|
||||
stdio: 'inherit',
|
||||
const previewProcess = await exec(astroBin, ['preview', '--port', port], {
|
||||
nodeOptions: {
|
||||
cwd: root,
|
||||
stdio: 'inherit',
|
||||
},
|
||||
});
|
||||
|
||||
console.log('Waiting for server ready...');
|
||||
|
@ -59,7 +61,7 @@ export async function run(projectDir, outputFile) {
|
|||
/**
|
||||
* @returns {Promise<import('autocannon').Result>}
|
||||
*/
|
||||
async function benchmarkCannon() {
|
||||
export async function benchmarkCannon() {
|
||||
return new Promise((resolve, reject) => {
|
||||
const instance = autocannon(
|
||||
{
|
||||
|
@ -76,7 +78,7 @@ async function benchmarkCannon() {
|
|||
instance.stop();
|
||||
resolve(result);
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
autocannon.track(instance, { renderResultsTable: false });
|
||||
});
|
||||
|
@ -95,7 +97,7 @@ function printResult(output) {
|
|||
],
|
||||
{
|
||||
align: ['l', 'r', 'r', 'r'],
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
const reqAndBytesTable = markdownTable(
|
||||
|
@ -106,7 +108,7 @@ function printResult(output) {
|
|||
],
|
||||
{
|
||||
align: ['l', 'r', 'r', 'r', 'r'],
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
return `${latencyTable}\n\n${reqAndBytesTable}`;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import mri from 'mri';
|
||||
import fs from 'node:fs/promises';
|
||||
import path from 'node:path';
|
||||
import { pathToFileURL } from 'node:url';
|
||||
import {fileURLToPath, pathToFileURL} from 'node:url';
|
||||
|
||||
const args = mri(process.argv.slice(2));
|
||||
|
||||
|
@ -14,6 +14,7 @@ Command
|
|||
memory Run build memory and speed test
|
||||
render Run rendering speed test
|
||||
server-stress Run server stress test
|
||||
codspeed Run codspeed test
|
||||
cli-startup Run CLI startup speed test
|
||||
|
||||
Options
|
||||
|
@ -29,6 +30,7 @@ const benchmarks = {
|
|||
render: () => import('./bench/render.js'),
|
||||
'server-stress': () => import('./bench/server-stress.js'),
|
||||
'cli-startup': () => import('./bench/cli-startup.js'),
|
||||
codspeed: () => import('./bench/codspeed.js')
|
||||
};
|
||||
|
||||
if (commandName && !(commandName in benchmarks)) {
|
||||
|
@ -37,12 +39,26 @@ if (commandName && !(commandName in benchmarks)) {
|
|||
}
|
||||
|
||||
if (commandName) {
|
||||
// Run single benchmark
|
||||
const bench = benchmarks[commandName];
|
||||
const benchMod = await bench();
|
||||
const projectDir = await makeProject(args.project || benchMod.defaultProject);
|
||||
const outputFile = await getOutputFile(commandName);
|
||||
await benchMod.run(projectDir, outputFile);
|
||||
if (commandName === 'codspeed') {
|
||||
const render = await makeProject('render-bench');
|
||||
const rootRender = fileURLToPath(render);
|
||||
const bench = benchmarks[commandName];
|
||||
const benchMod = await bench();
|
||||
const payload = {
|
||||
render: {
|
||||
root: rootRender,
|
||||
output: await getOutputFile('render')
|
||||
},
|
||||
};
|
||||
await benchMod.run(payload);
|
||||
} else {
|
||||
// Run single benchmark
|
||||
const bench = benchmarks[commandName];
|
||||
const benchMod = await bench();
|
||||
const projectDir = await makeProject(args.project || benchMod.defaultProject);
|
||||
const outputFile = await getOutputFile(commandName);
|
||||
await benchMod.run(projectDir, outputFile);
|
||||
}
|
||||
} else {
|
||||
// Run all benchmarks
|
||||
for (const name in benchmarks) {
|
||||
|
@ -54,7 +70,7 @@ if (commandName) {
|
|||
}
|
||||
}
|
||||
|
||||
async function makeProject(name) {
|
||||
export async function makeProject(name) {
|
||||
console.log('Making project:', name);
|
||||
const projectDir = new URL(`./projects/${name}/`, import.meta.url);
|
||||
|
||||
|
@ -78,6 +94,5 @@ async function getOutputFile(benchmarkName) {
|
|||
|
||||
// Prepare output file directory
|
||||
await fs.mkdir(new URL('./', file), { recursive: true });
|
||||
|
||||
return file;
|
||||
}
|
||||
|
|
132
benchmark/make-project/render-bench.js
Normal file
132
benchmark/make-project/render-bench.js
Normal file
|
@ -0,0 +1,132 @@
|
|||
import fs from 'node:fs/promises';
|
||||
import { loremIpsumHtml, loremIpsumMd } from './_util.js';
|
||||
|
||||
// Map of files to be generated and tested for rendering.
|
||||
// Ideally each content should be similar for comparison.
|
||||
const renderFiles = {
|
||||
'components/ListItem.astro': `\
|
||||
---
|
||||
const { className, item, attrs } = Astro.props;
|
||||
const nested = item !== 0;
|
||||
---
|
||||
<li class={className}>
|
||||
<a
|
||||
href={item}
|
||||
aria-current={item === 0}
|
||||
class:list={[{ large: !nested }, className]}
|
||||
{...attrs}
|
||||
>
|
||||
<span>{item}</span>
|
||||
</a>
|
||||
</li>
|
||||
`,
|
||||
'components/Sublist.astro': `\
|
||||
---
|
||||
import ListItem from '../components/ListItem.astro';
|
||||
const { items } = Astro.props;
|
||||
const className = "text-red-500";
|
||||
const style = { color: "red" };
|
||||
---
|
||||
<ul style={style}>
|
||||
{items.map((item) => (
|
||||
<ListItem className={className} item={item} attrs={{}} />
|
||||
))}
|
||||
</ul>
|
||||
`,
|
||||
'pages/astro.astro': `\
|
||||
---
|
||||
const className = "text-red-500";
|
||||
const style = { color: "red" };
|
||||
const items = Array.from({ length: 10000 }, (_, i) => ({i}));
|
||||
---
|
||||
<html>
|
||||
<head>
|
||||
<title>My Site</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1 class={className + ' text-lg'}>List</h1>
|
||||
<ul style={style}>
|
||||
{items.map((item) => (
|
||||
<li class={className}>
|
||||
<a
|
||||
href={item.i}
|
||||
aria-current={item.i === 0}
|
||||
class:list={[{ large: item.i === 0 }, className]}
|
||||
{...({})}
|
||||
>
|
||||
<span>{item.i}</span>
|
||||
</a>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
${Array.from({ length: 1000 })
|
||||
.map(() => `<p>${loremIpsumHtml}</p>`)
|
||||
.join('\n')}
|
||||
</body>
|
||||
</html>`,
|
||||
'pages/md.md': `\
|
||||
# List
|
||||
|
||||
${Array.from({ length: 1000 }, (_, i) => i)
|
||||
.map((v) => `- ${v}`)
|
||||
.join('\n')}
|
||||
|
||||
${Array.from({ length: 1000 })
|
||||
.map(() => loremIpsumMd)
|
||||
.join('\n\n')}
|
||||
`,
|
||||
'pages/mdx.mdx': `\
|
||||
export const className = "text-red-500";
|
||||
export const style = { color: "red" };
|
||||
export const items = Array.from({ length: 1000 }, (_, i) => i);
|
||||
|
||||
# List
|
||||
|
||||
<ul style={style}>
|
||||
{items.map((item) => (
|
||||
<li class={className}>{item}</li>
|
||||
))}
|
||||
</ul>
|
||||
|
||||
${Array.from({ length: 1000 })
|
||||
.map(() => loremIpsumMd)
|
||||
.join('\n\n')}
|
||||
`,
|
||||
};
|
||||
|
||||
export const renderPages = [];
|
||||
for (const file of Object.keys(renderFiles)) {
|
||||
if (file.startsWith('pages/')) {
|
||||
renderPages.push(file.replace('pages/', ''));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {URL} projectDir
|
||||
*/
|
||||
export async function run(projectDir) {
|
||||
await fs.rm(projectDir, { recursive: true, force: true });
|
||||
await fs.mkdir(new URL('./src/pages', projectDir), { recursive: true });
|
||||
await fs.mkdir(new URL('./src/components', projectDir), { recursive: true });
|
||||
|
||||
await Promise.all(
|
||||
Object.entries(renderFiles).map(([name, content]) => {
|
||||
return fs.writeFile(new URL(`./src/${name}`, projectDir), content, 'utf-8');
|
||||
})
|
||||
);
|
||||
|
||||
await fs.writeFile(
|
||||
new URL('./astro.config.js', projectDir),
|
||||
`\
|
||||
import { defineConfig } from 'astro/config';
|
||||
import adapter from '@benchmark/adapter';
|
||||
import mdx from '@astrojs/mdx';
|
||||
|
||||
export default defineConfig({
|
||||
integrations: [mdx()],
|
||||
output: 'server',
|
||||
adapter: adapter(),
|
||||
});`,
|
||||
'utf-8'
|
||||
);
|
||||
}
|
|
@ -10,6 +10,7 @@
|
|||
"@astrojs/mdx": "workspace:*",
|
||||
"@astrojs/node": "^8.3.4",
|
||||
"@benchmark/timer": "workspace:*",
|
||||
"@benchmark/adapter": "workspace:*",
|
||||
"astro": "workspace:*",
|
||||
"autocannon": "^7.15.0",
|
||||
"markdown-table": "^3.0.4",
|
||||
|
@ -18,5 +19,9 @@
|
|||
"pretty-bytes": "^6.1.1",
|
||||
"sharp": "^0.33.3",
|
||||
"tinyexec": "^0.3.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@codspeed/tinybench-plugin": "^3.1.1",
|
||||
"tinybench": "^2.9.0"
|
||||
}
|
||||
}
|
||||
|
|
3
benchmark/packages/adapter/README.md
Normal file
3
benchmark/packages/adapter/README.md
Normal file
|
@ -0,0 +1,3 @@
|
|||
# @benchmark/timer
|
||||
|
||||
Like `@astrojs/node`, but returns the rendered time in milliseconds for the page instead of the page content itself. This is used for internal benchmarks only.
|
35
benchmark/packages/adapter/package.json
Normal file
35
benchmark/packages/adapter/package.json
Normal file
|
@ -0,0 +1,35 @@
|
|||
{
|
||||
"name": "@benchmark/adapter",
|
||||
"description": "Bench adapter",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"type": "module",
|
||||
"types": "./dist/index.d.ts",
|
||||
"author": "withastro",
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
"withastro",
|
||||
"astro-adapter"
|
||||
],
|
||||
"exports": {
|
||||
".": "./dist/index.js",
|
||||
"./server.js": "./dist/server.js",
|
||||
"./package.json": "./package.json"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "astro-scripts build \"src/**/*.ts\" && tsc",
|
||||
"build:ci": "astro-scripts build \"src/**/*.ts\"",
|
||||
"dev": "astro-scripts dev \"src/**/*.ts\""
|
||||
},
|
||||
"dependencies": {
|
||||
"server-destroy": "^1.0.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"astro": "workspace:*"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/server-destroy": "^1.0.4",
|
||||
"astro": "workspace:*",
|
||||
"astro-scripts": "workspace:*"
|
||||
}
|
||||
}
|
32
benchmark/packages/adapter/src/index.ts
Normal file
32
benchmark/packages/adapter/src/index.ts
Normal file
|
@ -0,0 +1,32 @@
|
|||
import type { AstroAdapter, AstroIntegration } from 'astro';
|
||||
|
||||
export default function createIntegration(): AstroIntegration {
|
||||
return {
|
||||
name: '@benchmark/timer',
|
||||
hooks: {
|
||||
'astro:config:setup': ({ updateConfig }) => {
|
||||
updateConfig({
|
||||
vite: {
|
||||
ssr: {
|
||||
noExternal: ['@benchmark/timer'],
|
||||
},
|
||||
},
|
||||
});
|
||||
},
|
||||
'astro:config:done': ({ setAdapter }) => {
|
||||
setAdapter({
|
||||
name: '@benchmark/adapter',
|
||||
serverEntrypoint: '@benchmark/adapter/server.js',
|
||||
exports: ['manifest', 'createApp'],
|
||||
supportedAstroFeatures: {
|
||||
serverOutput: 'stable',
|
||||
envGetSecret: 'experimental',
|
||||
staticOutput: 'stable',
|
||||
hybridOutput: 'stable',
|
||||
i18nDomains: 'stable',
|
||||
},
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
34
benchmark/packages/adapter/src/server.ts
Normal file
34
benchmark/packages/adapter/src/server.ts
Normal file
|
@ -0,0 +1,34 @@
|
|||
import * as fs from 'node:fs';
|
||||
import type { SSRManifest } from 'astro';
|
||||
import { App } from 'astro/app';
|
||||
import { applyPolyfills } from 'astro/app/node';
|
||||
|
||||
applyPolyfills();
|
||||
|
||||
class MyApp extends App {
|
||||
#manifest: SSRManifest | undefined;
|
||||
#streaming: boolean;
|
||||
constructor(manifest: SSRManifest, streaming = false) {
|
||||
super(manifest, streaming);
|
||||
this.#manifest = manifest;
|
||||
this.#streaming = streaming;
|
||||
}
|
||||
|
||||
async render(request: Request) {
|
||||
const url = new URL(request.url);
|
||||
if (this.#manifest?.assets.has(url.pathname)) {
|
||||
const filePath = new URL('../../client/' + this.removeBase(url.pathname), import.meta.url);
|
||||
const data = await fs.promises.readFile(filePath);
|
||||
return new Response(data);
|
||||
}
|
||||
|
||||
return super.render(request);
|
||||
}
|
||||
}
|
||||
|
||||
export function createExports(manifest: SSRManifest) {
|
||||
return {
|
||||
manifest,
|
||||
createApp: (streaming: boolean) => new MyApp(manifest, streaming),
|
||||
};
|
||||
}
|
7
benchmark/packages/adapter/tsconfig.json
Normal file
7
benchmark/packages/adapter/tsconfig.json
Normal file
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"extends": "../../../tsconfig.base.json",
|
||||
"include": ["src"],
|
||||
"compilerOptions": {
|
||||
"outDir": "./dist"
|
||||
}
|
||||
}
|
|
@ -6,7 +6,9 @@ export function getAdapter(): AstroAdapter {
|
|||
serverEntrypoint: '@benchmark/timer/server.js',
|
||||
previewEntrypoint: '@benchmark/timer/preview.js',
|
||||
exports: ['handler'],
|
||||
supportedAstroFeatures: {},
|
||||
supportedAstroFeatures: {
|
||||
serverOutput: 'stable',
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,6 @@ export function createExports(manifest: SSRManifest) {
|
|||
const end = performance.now();
|
||||
res.write(end - start + '');
|
||||
res.end();
|
||||
},
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
12
biome.jsonc
12
biome.jsonc
|
@ -9,20 +9,16 @@
|
|||
"**/_temp-fixtures/**",
|
||||
"**/vendor/**",
|
||||
"**/.vercel/**",
|
||||
"benchmark/projects/",
|
||||
"benchmark/results/",
|
||||
],
|
||||
"include": ["test/**", "e2e/**", "packages/**", "/scripts/**"],
|
||||
"include": ["test/**", "e2e/**", "packages/**", "/scripts/**", "benchmark/bench"],
|
||||
},
|
||||
"formatter": {
|
||||
"indentStyle": "tab",
|
||||
"indentWidth": 2,
|
||||
"lineWidth": 100,
|
||||
"ignore": [
|
||||
"benchmark/projects/",
|
||||
"benchmark/results/",
|
||||
".changeset",
|
||||
"pnpm-lock.yaml",
|
||||
"*.astro",
|
||||
],
|
||||
"ignore": [".changeset", "pnpm-lock.yaml", "*.astro"],
|
||||
},
|
||||
"organizeImports": {
|
||||
"enabled": true,
|
||||
|
|
123
pnpm-lock.yaml
123
pnpm-lock.yaml
|
@ -66,6 +66,9 @@ importers:
|
|||
'@astrojs/node':
|
||||
specifier: ^8.3.4
|
||||
version: 8.3.4(astro@packages+astro)
|
||||
'@benchmark/adapter':
|
||||
specifier: workspace:*
|
||||
version: link:packages/adapter
|
||||
'@benchmark/timer':
|
||||
specifier: workspace:*
|
||||
version: link:packages/timer
|
||||
|
@ -93,6 +96,29 @@ importers:
|
|||
tinyexec:
|
||||
specifier: ^0.3.1
|
||||
version: 0.3.1
|
||||
devDependencies:
|
||||
'@codspeed/tinybench-plugin':
|
||||
specifier: ^3.1.1
|
||||
version: 3.1.1(tinybench@2.9.0)
|
||||
tinybench:
|
||||
specifier: ^2.9.0
|
||||
version: 2.9.0
|
||||
|
||||
benchmark/packages/adapter:
|
||||
dependencies:
|
||||
server-destroy:
|
||||
specifier: ^1.0.1
|
||||
version: 1.0.1
|
||||
devDependencies:
|
||||
'@types/server-destroy':
|
||||
specifier: ^1.0.4
|
||||
version: 1.0.4
|
||||
astro:
|
||||
specifier: workspace:*
|
||||
version: link:../../../packages/astro
|
||||
astro-scripts:
|
||||
specifier: workspace:*
|
||||
version: link:../../../scripts
|
||||
|
||||
benchmark/packages/timer:
|
||||
dependencies:
|
||||
|
@ -5935,6 +5961,14 @@ packages:
|
|||
bundledDependencies:
|
||||
- is-unicode-supported
|
||||
|
||||
'@codspeed/core@3.1.1':
|
||||
resolution: {integrity: sha512-ONhERVDAtkm0nc+FYPivDozoMOlNUP2BWRBFDJYATGA18Iap5Kd2mZ1/Lwz54RB5+g+3YDOpsvotHa4hd3Q+7Q==}
|
||||
|
||||
'@codspeed/tinybench-plugin@3.1.1':
|
||||
resolution: {integrity: sha512-LVF4End0kDU9V7CzuwAcmngSPJNnpduPnr+csOKvcG++FsYwfUuBJ1rvLPtv6yTkvxpUmUEsj6VA7/AEIBGZVw==}
|
||||
peerDependencies:
|
||||
tinybench: ^2.3.0
|
||||
|
||||
'@colors/colors@1.5.0':
|
||||
resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==}
|
||||
engines: {node: '>=0.1.90'}
|
||||
|
@ -7399,6 +7433,9 @@ packages:
|
|||
peerDependencies:
|
||||
postcss: ^8.1.0
|
||||
|
||||
axios@1.7.7:
|
||||
resolution: {integrity: sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==}
|
||||
|
||||
axobject-query@4.1.0:
|
||||
resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
@ -8212,6 +8249,10 @@ packages:
|
|||
resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
find-up@6.3.0:
|
||||
resolution: {integrity: sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==}
|
||||
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
|
||||
|
||||
find-yarn-workspace-root2@1.2.16:
|
||||
resolution: {integrity: sha512-hr6hb1w8ePMpPVUK39S4RlwJzi+xPLuVuG8XlwXU3KD5Yn3qgBWVfy3AzNlDhWvE1EORCE65/Qm26rFQt3VLVA==}
|
||||
|
||||
|
@ -8226,6 +8267,15 @@ packages:
|
|||
resolution: {integrity: sha512-9UbaD6XdAL97+k/n+N7JwX46K/M6Zc6KcFYskrYL8wbBV/Uyk0CTAMY0VT+qiK5PM7AIc9aTWYtq65U7T+aCNQ==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
follow-redirects@1.15.9:
|
||||
resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==}
|
||||
engines: {node: '>=4.0'}
|
||||
peerDependencies:
|
||||
debug: '*'
|
||||
peerDependenciesMeta:
|
||||
debug:
|
||||
optional: true
|
||||
|
||||
foreground-child@3.3.0:
|
||||
resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==}
|
||||
engines: {node: '>=14'}
|
||||
|
@ -8751,6 +8801,10 @@ packages:
|
|||
resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
locate-path@7.2.0:
|
||||
resolution: {integrity: sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==}
|
||||
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
|
||||
|
||||
lodash.chunk@4.2.0:
|
||||
resolution: {integrity: sha512-ZzydJKfUHJwHa+hF5X66zLFCBrWn5GeF28OHEr4WVWtNDXlQ/IjWKPBiikqKo2ne0+v6JgCgJ0GzJp8k8bHC7w==}
|
||||
|
||||
|
@ -9174,6 +9228,10 @@ packages:
|
|||
resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==}
|
||||
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
|
||||
|
||||
node-gyp-build@4.8.2:
|
||||
resolution: {integrity: sha512-IRUxE4BVsHWXkV/SFOut4qTlagw2aM8T5/vnTsmrHJvVoKueJHRc/JaFND7QDDc61kLYUJ6qlZM3sqTSyx2dTw==}
|
||||
hasBin: true
|
||||
|
||||
node-html-parser@6.1.13:
|
||||
resolution: {integrity: sha512-qIsTMOY4C/dAa5Q5vsobRpOOvPfC4pB61UVW2uSwZNUp0QU/jCekTal1vMmbO0DgdHeLUJpv/ARmDqErVxA3Sg==}
|
||||
|
||||
|
@ -9276,6 +9334,10 @@ packages:
|
|||
resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
p-limit@4.0.0:
|
||||
resolution: {integrity: sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==}
|
||||
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
|
||||
|
||||
p-limit@6.1.0:
|
||||
resolution: {integrity: sha512-H0jc0q1vOzlEk0TqAKXKZxdl7kX3OFUzCnNVUnq5Pc3DGo0kpeaMuPqxQn235HibwBEb0/pm9dgKTjXy66fBkg==}
|
||||
engines: {node: '>=18'}
|
||||
|
@ -9288,6 +9350,10 @@ packages:
|
|||
resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
p-locate@6.0.0:
|
||||
resolution: {integrity: sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==}
|
||||
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
|
||||
|
||||
p-map@2.1.0:
|
||||
resolution: {integrity: sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==}
|
||||
engines: {node: '>=6'}
|
||||
|
@ -9352,6 +9418,10 @@ packages:
|
|||
resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
path-exists@5.0.0:
|
||||
resolution: {integrity: sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==}
|
||||
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
|
||||
|
||||
path-key@3.1.1:
|
||||
resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
|
||||
engines: {node: '>=8'}
|
||||
|
@ -9687,6 +9757,9 @@ packages:
|
|||
property-information@6.5.0:
|
||||
resolution: {integrity: sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig==}
|
||||
|
||||
proxy-from-env@1.1.0:
|
||||
resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
|
||||
|
||||
pseudomap@1.0.2:
|
||||
resolution: {integrity: sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==}
|
||||
|
||||
|
@ -11501,6 +11574,23 @@ snapshots:
|
|||
picocolors: 1.1.0
|
||||
sisteransi: 1.0.5
|
||||
|
||||
'@codspeed/core@3.1.1':
|
||||
dependencies:
|
||||
axios: 1.7.7
|
||||
find-up: 6.3.0
|
||||
form-data: 4.0.0
|
||||
node-gyp-build: 4.8.2
|
||||
transitivePeerDependencies:
|
||||
- debug
|
||||
|
||||
'@codspeed/tinybench-plugin@3.1.1(tinybench@2.9.0)':
|
||||
dependencies:
|
||||
'@codspeed/core': 3.1.1
|
||||
stack-trace: 1.0.0-pre2
|
||||
tinybench: 2.9.0
|
||||
transitivePeerDependencies:
|
||||
- debug
|
||||
|
||||
'@colors/colors@1.5.0':
|
||||
optional: true
|
||||
|
||||
|
@ -13033,6 +13123,14 @@ snapshots:
|
|||
postcss: 8.4.47
|
||||
postcss-value-parser: 4.2.0
|
||||
|
||||
axios@1.7.7:
|
||||
dependencies:
|
||||
follow-redirects: 1.15.9
|
||||
form-data: 4.0.0
|
||||
proxy-from-env: 1.1.0
|
||||
transitivePeerDependencies:
|
||||
- debug
|
||||
|
||||
axobject-query@4.1.0: {}
|
||||
|
||||
babel-plugin-jsx-dom-expressions@0.38.5(@babel/core@7.26.0):
|
||||
|
@ -13771,6 +13869,11 @@ snapshots:
|
|||
locate-path: 6.0.0
|
||||
path-exists: 4.0.0
|
||||
|
||||
find-up@6.3.0:
|
||||
dependencies:
|
||||
locate-path: 7.2.0
|
||||
path-exists: 5.0.0
|
||||
|
||||
find-yarn-workspace-root2@1.2.16:
|
||||
dependencies:
|
||||
micromatch: 4.0.8
|
||||
|
@ -13785,6 +13888,8 @@ snapshots:
|
|||
|
||||
flattie@1.1.1: {}
|
||||
|
||||
follow-redirects@1.15.9: {}
|
||||
|
||||
foreground-child@3.3.0:
|
||||
dependencies:
|
||||
cross-spawn: 7.0.3
|
||||
|
@ -14418,6 +14523,10 @@ snapshots:
|
|||
dependencies:
|
||||
p-locate: 5.0.0
|
||||
|
||||
locate-path@7.2.0:
|
||||
dependencies:
|
||||
p-locate: 6.0.0
|
||||
|
||||
lodash.chunk@4.2.0: {}
|
||||
|
||||
lodash.clonedeep@4.5.0: {}
|
||||
|
@ -15091,6 +15200,8 @@ snapshots:
|
|||
fetch-blob: 3.2.0
|
||||
formdata-polyfill: 4.0.10
|
||||
|
||||
node-gyp-build@4.8.2: {}
|
||||
|
||||
node-html-parser@6.1.13:
|
||||
dependencies:
|
||||
css-select: 5.1.0
|
||||
|
@ -15201,6 +15312,10 @@ snapshots:
|
|||
dependencies:
|
||||
yocto-queue: 0.1.0
|
||||
|
||||
p-limit@4.0.0:
|
||||
dependencies:
|
||||
yocto-queue: 1.1.1
|
||||
|
||||
p-limit@6.1.0:
|
||||
dependencies:
|
||||
yocto-queue: 1.1.1
|
||||
|
@ -15213,6 +15328,10 @@ snapshots:
|
|||
dependencies:
|
||||
p-limit: 3.1.0
|
||||
|
||||
p-locate@6.0.0:
|
||||
dependencies:
|
||||
p-limit: 4.0.0
|
||||
|
||||
p-map@2.1.0: {}
|
||||
|
||||
p-queue@8.0.1:
|
||||
|
@ -15282,6 +15401,8 @@ snapshots:
|
|||
|
||||
path-exists@4.0.0: {}
|
||||
|
||||
path-exists@5.0.0: {}
|
||||
|
||||
path-key@3.1.1: {}
|
||||
|
||||
path-key@4.0.0: {}
|
||||
|
@ -15631,6 +15752,8 @@ snapshots:
|
|||
|
||||
property-information@6.5.0: {}
|
||||
|
||||
proxy-from-env@1.1.0: {}
|
||||
|
||||
pseudomap@1.0.2: {}
|
||||
|
||||
psl@1.9.0: {}
|
||||
|
|
Loading…
Reference in a new issue