From 2d693c865cf87ba02c1f10e48512b6e705a2a8af Mon Sep 17 00:00:00 2001 From: Brooklyn Nicholson Date: Thu, 16 Apr 2026 15:21:49 -0500 Subject: [PATCH] perf(tui): spawn python gateway before loading @hermes/ink MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Before: entry.tsx imports @hermes/ink (394KB bundle) + App + GatewayClient in declaration order, then calls `gw.start()` at ~T=220ms. Python fork + server.py import starts then. After: only `GatewayClient` is statically imported (5ms, node builtins only). `gw.start()` fires at ~T=5ms. @hermes/ink + App load in parallel via `Promise.all(import(...))`. Python gets ~215ms of free runway to do its own module import before node even finishes loading. Net: session.info arrives ~150ms earlier in cold start. First React frame timing is unchanged (still ~240ms — still gated by ink+app imports). Removed a previously-tried warm-thread in server.py that pre-imported `run_agent` in the background. Measured variance showed occasional 5-10s outliers (GIL thrashing); median gain was <100ms. Not worth the non-determinism. --- ui-tui/src/entry.tsx | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/ui-tui/src/entry.tsx b/ui-tui/src/entry.tsx index 3ab4be96ba..abbcf7a4c8 100644 --- a/ui-tui/src/entry.tsx +++ b/ui-tui/src/entry.tsx @@ -1,7 +1,8 @@ #!/usr/bin/env node -import { render } from '@hermes/ink' - -import { App } from './app.js' +// Import order matters for cold start: `GatewayClient` has only node-builtin +// deps (<20ms), so spawning the python gateway before loading @hermes/ink +// + App (~200ms combined) gives python ~200ms of free parallel time to run +// its own module imports instead of starting those after node is done. import { GatewayClient } from './gatewayClient.js' if (!process.stdin.isTTY) { @@ -11,6 +12,7 @@ if (!process.stdin.isTTY) { const gw = new GatewayClient() gw.start() -render(, { - exitOnCtrlC: false -}) + +const [{ render }, { App }] = await Promise.all([import('@hermes/ink'), import('./app.js')]) + +render(, { exitOnCtrlC: false })