perfshield
v0.0.10
Published
A tool for doing web benchmarking across multiple JS engines and with statistical signifigance
Readme
perfshield
perfshield is a build-system-agnostic benchmarking tool for comparing two versions of a JavaScript library across JS runtimes. It borrows statistical ideas from Tachometer (confidence intervals, adaptive sampling) and focuses on runtime JS engines (Node/V8 today).
What it does
- Builds your benchmark bundle using your own build command.
- Saves a baseline bundle (
prepare). - Builds the current bundle and compares it to the baseline (
compare). - Reports results in console and/or JSON.
- Exits with code 1 when a regression is detected (both relative and absolute CIs exclude 0 in the slower direction).
Requirements
- Node.js (used for the CLI and the Node engine).
- A build command that emits a single ESM benchmark bundle.
Install
pnpm add -D perfshieldQuick start
- Create a benchmark module that exports
benchmarks:
export const benchmarks = [
{
name: "sum",
iterations: 1,
async fn() {
let total = 0;
for (let i = 0; i < 10_000; i += 1) {
total += i;
}
return total;
},
},
];- Create a
perfshield.config.json:
{
"artifactsDir": ".perfshield",
"build": {
"command": "pnpm run build:bench",
"output": "dist/bench.js"
},
"engines": [
{
"name": "node",
"command": "node"
}
],
"sampling": {
"minSamples": 30,
"timeoutMs": 10000,
"conditions": [0]
},
"report": {
"formats": ["console", "json"]
}
}- Run the workflow:
perfshield prepare --config perfshield.config.json
perfshield compare --config perfshield.config.json- (Optional) Calibrate sampling defaults based on the prepared baseline:
perfshield calibrate --config perfshield.config.jsonThis prints a JSON snippet with recommended sampling values you can paste into
your config.
Benchmark bundle contract
The build output must be a single ESM file that exports:
export const benchmarks = [
{
name: "example",
fn: async () => {},
setup: async () => {},
teardown: async () => {},
unit: "ms",
iterations: 1,
metadata: { tag: "optional" },
},
];Rules:
benchmarksis required.fnis required.setup/teardownrun once per sample (per benchmark, per version).- If
setupthrows, the sample fails and the run is aborted. iterationsrepeatsfninside a single sample to reduce noise.
Artifacts
preparestores a baseline bundle inartifactsDir(default.perfshield).compareuses the stored baseline and the newly built bundle.
Reports
Supported formats:
console: human‑readable summary.json: machine‑readable report.
If any benchmark shows a regression (both relative and absolute CIs exclude 0 in the slower direction), the process exits with code 1.
Examples
See examples/simple for a minimal setup you can run locally.
