rolldown-perf-kit 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +345 -0
- package/LICENSE +25 -0
- package/README.md +621 -2
- package/harness.mjs +4860 -0
- package/lib/build.mjs +57 -0
- package/lib/cdp.mjs +217 -0
- package/lib/chunk-discovery.mjs +226 -0
- package/lib/coverage.mjs +498 -0
- package/lib/field/analysis.mjs +225 -0
- package/lib/field/browser.mjs +232 -0
- package/lib/field/build-match.mjs +86 -0
- package/lib/field/capture.mjs +501 -0
- package/lib/field/config.mjs +84 -0
- package/lib/field/run.mjs +612 -0
- package/lib/gen-app.mjs +399 -0
- package/lib/graph-diff.mjs +136 -0
- package/lib/interrupt.mjs +25 -0
- package/lib/measure.mjs +540 -0
- package/lib/min-cut.mjs +218 -0
- package/lib/module-graph.mjs +318 -0
- package/lib/network-evidence.mjs +84 -0
- package/lib/node/launch.mjs +351 -0
- package/lib/node/measure.mjs +289 -0
- package/lib/paint-diagnostics.mjs +76 -0
- package/lib/parity/anchor.mjs +186 -0
- package/lib/parity/capture.mjs +527 -0
- package/lib/parity/compare.mjs +813 -0
- package/lib/parity/png.mjs +166 -0
- package/lib/parity/run.mjs +145 -0
- package/lib/profile.mjs +281 -0
- package/lib/replay/cert.mjs +45 -0
- package/lib/replay/model.mjs +656 -0
- package/lib/replay/run.mjs +1140 -0
- package/lib/replay/server.mjs +499 -0
- package/lib/replay/shaper.mjs +158 -0
- package/lib/rolldown-support.mjs +161 -0
- package/lib/serve.mjs +142 -0
- package/lib/worker/attrib.mjs +125 -0
- package/lib/worker/config.mjs +116 -0
- package/lib/worker/launch.mjs +337 -0
- package/lib/worker/measure.mjs +296 -0
- package/package.json +38 -4
- package/replay.mjs +79 -0
package/replay.mjs
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// perf-kit-replay - record a deployed page once, replay it against local builds.
|
|
3
|
+
// Standalone: no harness target, no lab state. The archive folder is the whole
|
|
4
|
+
// interface between the agent that records and the agent that replays.
|
|
5
|
+
|
|
6
|
+
import { cmdInspect, cmdRecord, cmdReplay } from './lib/replay/run.mjs';
|
|
7
|
+
|
|
8
|
+
const HELP = `perf-kit-replay - field-like load numbers for builds that are not deployed
|
|
9
|
+
|
|
10
|
+
record load a deployed page in the user's logged-in Chrome and write an archive
|
|
11
|
+
inspect what an archive holds, whether it is complete, the next commands
|
|
12
|
+
replay serve an archive to headless Chrome with local builds in place of the deployed files
|
|
13
|
+
|
|
14
|
+
TWO AGENTS
|
|
15
|
+
recording agent (needs the user's Chrome with chrome://inspect/#remote-debugging on):
|
|
16
|
+
node replay.mjs record --url https://app.example.com/ [--cookie name=value]
|
|
17
|
+
[--block analytics.example.com] [--gate /api/items] [--ignore-lcp '#splash']
|
|
18
|
+
[--build <local copy of the served build>] --json
|
|
19
|
+
-> returns { archive, handoff, complete, gaps, next, ... }. complete:false -> record
|
|
20
|
+
again with a longer --settle. Hand over the "archive" path only.
|
|
21
|
+
replaying agent (no browser login needed):
|
|
22
|
+
node replay.mjs inspect --archive <dir> --json usable? complete? warnings? recorded when?
|
|
23
|
+
lateChunksBeforeLcp: late static chunks in the field runs
|
|
24
|
+
node replay.mjs replay --archive <dir> --dist recorded=<served build> --calibrate --json --exit-code
|
|
25
|
+
node replay.mjs replay --archive <dir> --dist base=<dir> --dist candidate=<dir> --json
|
|
26
|
+
The calibration verdict says what to do next:
|
|
27
|
+
pass an A/B on this archive is usable
|
|
28
|
+
record-again the archive misses responses most field runs got: record again
|
|
29
|
+
model-error the archive is complete; a new recording does not fix it: report the rows
|
|
30
|
+
Trust an A/B only after the calibration passes. HANDOFF.txt in the archive repeats this.
|
|
31
|
+
|
|
32
|
+
record
|
|
33
|
+
--url <page> --cookie name=value (repeat) --block <substring> (repeat) --gate <substring>
|
|
34
|
+
--ignore-lcp <selector> --redact <regex> (repeat) --variant <name> or: --config <field.json> [--variant <name>]
|
|
35
|
+
--build <dir> local copy of the build the site serves (calibration, HTML check)
|
|
36
|
+
--runs 6 --settle 3000 --pause 3000 --timeout 30000 --out <dir> --cdp-port <n> --cdp-url <ws>
|
|
37
|
+
Writes to $TMPDIR/perf-kit-replay/<site>-<variant> (owner-only; refuses a git work tree).
|
|
38
|
+
The archive holds REAL responses of the recording account: never copy it anywhere.
|
|
39
|
+
|
|
40
|
+
replay
|
|
41
|
+
--archive <dir> --dist [name=]<dir> (repeat for an A/B) --runs 6 --calibrate
|
|
42
|
+
--diagnose 1 [--cut gate|lcp|fcp] coverage + CPU profile run per dist
|
|
43
|
+
--document merged|local|recorded default merged: the dist's index.html + the tags only the deployed HTML has
|
|
44
|
+
--storage warm|empty warm: one unmeasured load in the same browser context first, so the build's
|
|
45
|
+
own storage (cached boot data) is there, as on a returning visit. Default warm
|
|
46
|
+
when the recorded page had localStorage, else empty
|
|
47
|
+
--bandwidth <Mbit/s> --rtt <ms> --static-ttfb <ms> --wire <kB> --ect slow-2g|2g|3g|4g|off model overrides
|
|
48
|
+
--out <dir> default <archive>/replay-report
|
|
49
|
+
|
|
50
|
+
common
|
|
51
|
+
--json print one JSON result object on stdout; the log goes to stderr
|
|
52
|
+
--exit-code replay --calibrate: exit 1 on model-error, 3 on record-again
|
|
53
|
+
exit codes 0 done, 1 model-error (--exit-code), 2 error, 3 record-again (--exit-code)`;
|
|
54
|
+
|
|
55
|
+
const [command, ...rest] = process.argv.slice(2);
|
|
56
|
+
const commands = { record: cmdRecord, inspect: cmdInspect, replay: cmdReplay };
|
|
57
|
+
if (!commands[command]) {
|
|
58
|
+
console.log(HELP);
|
|
59
|
+
process.exit(command && command !== 'help' ? 2 : 0);
|
|
60
|
+
}
|
|
61
|
+
const json = rest.includes('--json');
|
|
62
|
+
const exitOnFail = rest.includes('--exit-code');
|
|
63
|
+
const argv = rest.filter((a) => a !== '--json' && a !== '--exit-code');
|
|
64
|
+
const log = console.log;
|
|
65
|
+
if (json) console.log = (...args) => console.error(...args);
|
|
66
|
+
try {
|
|
67
|
+
const result = await commands[command](argv);
|
|
68
|
+
if (json) process.stdout.write(`${JSON.stringify(result)}\n`);
|
|
69
|
+
if (exitOnFail && result?.calibration) {
|
|
70
|
+
const codes = { pass: 0, 'model-error': 1, 'record-again': 3 };
|
|
71
|
+
process.exitCode = codes[result.calibration.verdict] ?? 1;
|
|
72
|
+
}
|
|
73
|
+
} catch (err) {
|
|
74
|
+
if (json) process.stdout.write(`${JSON.stringify({ error: err.message })}\n`);
|
|
75
|
+
console.error(`error: ${err.message}`);
|
|
76
|
+
process.exitCode = 2;
|
|
77
|
+
} finally {
|
|
78
|
+
console.log = log;
|
|
79
|
+
}
|