[PR #1439] [MERGED] perf(cli): defer Playwright and isomorphic-git until a command needs them #2888

Closed
opened 2026-10-17 21:11:26 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/morluto/rea/pull/1439
Author: @kaoru0822-kitauji
Created: 10/10/2026
Status: ✅ Merged
Merged: 10/10/2026
Merged by: @N0zoM1z0

Base: main ← Head: perf/cli-lazy-browser-scenario


📝 Commits (2)

  • d0971de perf(cli): load Playwright only for browser scenario captures
  • d992433 perf(cli): load isomorphic-git only when reading reference source Git state

📊 Changes

3 files changed (+81 additions, -3 deletions)

View changed files

📝 src/application/ReferenceSourceVcsAdapter.ts (+2 -2)
📝 src/cliBrowserScenarioCommands.ts (+3 -1)
➕ tests/boundary/cli/cliStartupImports.test.ts (+76 -0)

📄 Description

Summary

capture-browser-scenario imported its Playwright-backed provider (composition/browserScenario.js → PlaywrightScenarioBrowser → playwright-core) at module scope. Because the CLI registers every command at startup, every rea invocation loaded playwright-core, about 95 ms in a CPU profile, even for commands that never use a browser. The command now imports the composition when it runs. capture-electron-scenario already does this (src/cli/electronCommands.ts). This Playwright improvement applies to CLI command registration. Actual stdio MCP startup still resolves Playwright; loadOptionalObservationProviders invokes its dynamic provider factories during startup.

Agents that drive REA through the CLI pay this startup cost on every call. Related to the responsiveness work in #1065.

A second commit does the same for isomorphic-git. Only import-reference-source uses it, through ReferenceSourceVcsAdapter, but the static import also loaded it and its Buffer polyfills (sha.js, to-buffer, typed-array-buffer, …) in every CLI and MCP process.

Measurements (macOS arm64, Node 26.5, median of 12 runs after 2 warmups, both commits vs main)

Command main This PR
rea --version 477 ms 367 ms (−23%)
rea demangle-swift x 476 ms 368 ms (−23%)
rea list-architectures XLD 940 ms 824 ms (−12%)

Playwright alone accounted for about 95 ms and isomorphic-git for about 17 ms.

Change

  • src/cliBrowserScenarioCommands.ts: dynamic import("./composition/browserScenario.js") after input validation, in place of the static import.
  • src/application/ReferenceSourceVcsAdapter.ts: isomorphic-git is imported inside resolveSourceHead, which runs only when a .git entry exists. Import failures fall into the existing unknown VCS result, the same as unresolvable refs.
  • New tests/boundary/cli/cliStartupImports.test.ts: runs the built CLI with a module.registerHooks resolve hook that reports resolved playwright-core and isomorphic-git modules.
    • It asserts that rea --help resolves neither. This fails on main and passes here.
    • Control cases check that the hook does detect each package when its code actually runs (the browser scenario composition, and reading a directory that contains .git).

No contract, output, or error-shape change. Input validation errors are returned before the import, as before.

Verification

  • npm run test:focused -- tests/boundary/cli/cliStartupImports.test.ts, browserCli.test.ts, scenarioCliInputDiagnostics.test.ts, cliToolCoverage.test.ts, jsonInputStatus.test.ts, tests/evaluation/moduleBoundaries.test.ts, tests/boundary/filesystem/referenceSourceVcs.test.ts, referenceSourceImportStatus.test.ts, referenceSourceUtf8.test.ts: all pass.
  • Real run: rea capture-browser-scenario with headless Brave against a local page returned capture Evidence through the lazily loaded provider.
  • npm run typecheck, oxlint and oxfmt; the pre-push check:fast passed.

No real Hopper/Ghidra verification (not affected).

🤖 Generated with Claude Code


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/morluto/rea/pull/1439 **Author:** [@kaoru0822-kitauji](https://github.com/kaoru0822-kitauji) **Created:** 10/10/2026 **Status:** ✅ Merged **Merged:** 10/10/2026 **Merged by:** [@N0zoM1z0](https://github.com/N0zoM1z0) **Base:** `main` ← **Head:** `perf/cli-lazy-browser-scenario` --- ### 📝 Commits (2) - [`d0971de`](https://github.com/morluto/rea/commit/d0971def1f452d1edde85004c690c14627785137) perf(cli): load Playwright only for browser scenario captures - [`d992433`](https://github.com/morluto/rea/commit/d992433bd30619506852534e7009b9632f0cbade) perf(cli): load isomorphic-git only when reading reference source Git state ### 📊 Changes **3 files changed** (+81 additions, -3 deletions) <details> <summary>View changed files</summary> 📝 `src/application/ReferenceSourceVcsAdapter.ts` (+2 -2) 📝 `src/cliBrowserScenarioCommands.ts` (+3 -1) ➕ `tests/boundary/cli/cliStartupImports.test.ts` (+76 -0) </details> ### 📄 Description ## Summary `capture-browser-scenario` imported its Playwright-backed provider (`composition/browserScenario.js` → `PlaywrightScenarioBrowser` → `playwright-core`) at module scope. Because the CLI registers every command at startup, every `rea` invocation loaded `playwright-core`, about 95 ms in a CPU profile, even for commands that never use a browser. The command now imports the composition when it runs. `capture-electron-scenario` already does this (`src/cli/electronCommands.ts`). This Playwright improvement applies to CLI command registration. Actual stdio MCP startup still resolves Playwright; `loadOptionalObservationProviders` invokes its dynamic provider factories during startup. Agents that drive REA through the CLI pay this startup cost on every call. Related to the responsiveness work in #1065. A second commit does the same for `isomorphic-git`. Only `import-reference-source` uses it, through `ReferenceSourceVcsAdapter`, but the static import also loaded it and its Buffer polyfills (`sha.js`, `to-buffer`, `typed-array-buffer`, …) in every CLI and MCP process. ## Measurements (macOS arm64, Node 26.5, median of 12 runs after 2 warmups, both commits vs main) | Command | main | This PR | | --- | ---: | ---: | | `rea --version` | 477 ms | 367 ms (−23%) | | `rea demangle-swift x` | 476 ms | 368 ms (−23%) | | `rea list-architectures XLD` | 940 ms | 824 ms (−12%) | Playwright alone accounted for about 95 ms and isomorphic-git for about 17 ms. ## Change - `src/cliBrowserScenarioCommands.ts`: dynamic `import("./composition/browserScenario.js")` after input validation, in place of the static import. - `src/application/ReferenceSourceVcsAdapter.ts`: `isomorphic-git` is imported inside `resolveSourceHead`, which runs only when a `.git` entry exists. Import failures fall into the existing `unknown` VCS result, the same as unresolvable refs. - New `tests/boundary/cli/cliStartupImports.test.ts`: runs the built CLI with a `module.registerHooks` resolve hook that reports resolved `playwright-core` and `isomorphic-git` modules. - It asserts that `rea --help` resolves neither. This fails on main and passes here. - Control cases check that the hook does detect each package when its code actually runs (the browser scenario composition, and reading a directory that contains `.git`). No contract, output, or error-shape change. Input validation errors are returned before the import, as before. ## Verification - `npm run test:focused --` `tests/boundary/cli/cliStartupImports.test.ts`, `browserCli.test.ts`, `scenarioCliInputDiagnostics.test.ts`, `cliToolCoverage.test.ts`, `jsonInputStatus.test.ts`, `tests/evaluation/moduleBoundaries.test.ts`, `tests/boundary/filesystem/referenceSourceVcs.test.ts`, `referenceSourceImportStatus.test.ts`, `referenceSourceUtf8.test.ts`: all pass. - Real run: `rea capture-browser-scenario` with headless Brave against a local page returned capture Evidence through the lazily loaded provider. - `npm run typecheck`, oxlint and oxfmt; the pre-push `check:fast` passed. No real Hopper/Ghidra verification (not affected). 🤖 Generated with [Claude Code](https://claude.com/claude-code) --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
bsakaguchi 2026-10-17 21:11:26 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#2888
No description provided.