SearchCtrlK

  • ↑↓navigate
  • ↵open
  • escclose

Can’t find it? Contact us

@sdxc/bench

Bundle-weight and HTTP latency budgets for packages and running apps

Terminal
npm install @sdxc/bench
Terminal
pnpm add @sdxc/bench
Terminal
yarn add @sdxc/bench
Terminal
bun add @sdxc/bench
Depends on
esbuildremix

Bundle-weight and HTTP latency budgets for packages and running apps.

Hold a package entry to a gzipped size after a minified browser bundle, and sample latency against a URL that is already running.

Installation

Terminal
npm add @sdxc/bench

@sdxc/result and @sdxc/duration install alongside.

Usage

Weigh an entry point

typescript
import { weigh } from "@sdxc/bench";
import { unwrap } from "@sdxc/result";
import { expect, test } from "vitest";

test("the format entry stays small", async () => {
	let weight = unwrap(await weigh(new URL("./index.ts", import.meta.url).pathname));
	expect(weight.gzipped).toBeLessThan(25 * 1024);
});

The build targets the browser with every dependency inlined, so the number covers what a consumer pulls in. Gzipped size is the budget; minified is reported beside it for diagnosis.

Sample HTTP latency

typescript
import { sampleHttp } from "@sdxc/bench";
import { expect, test } from "vitest";

test("the health endpoint answers within budget", async () => {
	let report = await sampleHttp({
		url: "http://127.0.0.1:8787/health",
		requests: 20,
		concurrency: 5,
		timeoutMs: 5_000,
	});

	expect(report.failures).toBe(0);
	expect(report.p95).toBeLessThan(200);
	expect(report.p99).toBeLessThan(500);
});

failures counts requests that errored or timed out; ok is the rest of requests. Time budgets on the command line accept DurationInput: a string such as "200ms" or a bare millisecond number.

Command line

With @sdxc/kit installed, sdxc pkg bench runs the same checks from a terminal:

Terminal
sdxc pkg bench --help
sdxc pkg bench weigh ./src/index.ts --max-gzipped 25600
sdxc pkg bench http https://example.com/ --requests 20 --p95 200ms --json

--timeout, --p50, --p95, --p99 and --mean accept a duration string (200ms, 5s) or a bare millisecond number (200). Exit 1 when a budget fails or every request errors; exit 2 for usage or an invalid duration.

API

weigh(entry: string, root?: string): Promise<Result<Weight, WeightError>>

Bundles entry for the browser (minified, dependencies inlined) from root (default process.cwd()) and returns { minified, gzipped } in bytes.

assertWeight(weight, budget, entry?): Result<Weight, WeightError>

Answers a Result when weight.gzipped exceeds budget.maxGzipped, or when optional budget.maxMinified is set and missed. Used by the CLI's --max-gzipped flag; in tests, compare weight.gzipped with an expectation.

sampleHttp(options): Promise<HttpReport>

Issues requests with at most concurrency in flight, timing each with performance.now(). The report's ok / failures split those attempts, and min / mean / p50 / p95 / p99 / max cover the successful samples only.

assertHttpBudgets(report, budgets): Result<HttpReport, HttpBudgetError>

Answers a failure when a declared p50 / p95 / p99 / mean ceiling (milliseconds) is exceeded. Used by the CLI; in tests, compare the report's percentiles with expectations.

budgetMs(input) / parseBudgetFlag(text)

Normalize a DurationInput or a CLI flag ("200" / "200ms") to milliseconds.

API

Can’t find it? Contact us