perf(plugins): use native require for compiled JS before jiti

Every CLI invocation reads the config snapshot, which pulls bundled
channel doctor contracts and setup surfaces through
`getCachedPluginJitiLoader`. jiti's TS→JS transform pipeline adds
several seconds of per-load overhead on slower hosts (NAS profiling
shows ~78% of `openclaw config get` wall time spent inside the jiti
library), and that overhead is pure waste for the already-compiled
`.js` artifacts shipped in dist/.

Wrap the loader returned by `getCachedPluginJitiLoader` so that
compiled JS targets go through `tryNativeRequireJavaScriptModule`
first. Jiti stays on the hot path for:
- TS/TSX/MTS/CTS sources
- paths the native-require helper declines (Windows by default, or
  module-resolution fallbacks)

This centralises the fast path that already existed — inside
`doctor-contract-registry` and `channel-entry-contract` — and extends
it to every caller that goes through the jiti loader cache.

Benchmark on a modest NAS (Node 22.22, ZFS, telegram + discord
configured):

| command          | before | after |
|------------------|-------:|------:|
| config get X     |    24s |    6s |
| status           |    45s |   18s |
| devices list     |    55s |   26s |
| nodes status     |    55s |   26s |

Fixes the slow config/status/devices/nodes read paths reported in
openclaw#62842. Remaining time is dominated by non-jiti code paths
(config schema validation, eager provider-plugin module eval) that
are out of scope for this patch.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Effet
2026-04-24 21:59:19 +08:00
committed by Peter Steinberger
parent 6d60b035b4
commit b40b85c21a
4 changed files with 89 additions and 1 deletions

View File

@@ -8,6 +8,15 @@ import {
resetRegistryJitiMocks,
} from "./test-helpers/registry-jiti-mocks.js";
// jiti-loader-cache prefers native require() for compiled .js before falling
// back to jiti. These tests scripts plugin-loading behaviour through the
// jiti mock — disable the native-require fast path so the mocked jiti loader
// stays authoritative for the test fixture files on disk.
vi.mock("./native-module-require.js", () => ({
isJavaScriptModulePath: (_modulePath: string) => false,
tryNativeRequireJavaScriptModule: (_modulePath: string) => ({ ok: false }),
}));
const tempDirs: string[] = [];
const mocks = getRegistryJitiMocks();