hermes-agent/apps/desktop/scripts
Brooklyn Nicholson 0481766561 perf(desktop): make ⌘K cost nothing until it opens
⌘K is an overlay that is stateful to itself — pressing it owes the user a
frame immediately, whatever else the shell is doing. It was not built that
way.

`CommandPalette` is mounted for the life of the app, and its body ran
unconditionally: a dozen store subscriptions (connection, desktop version,
client + backend update status/apply, keybinds, worktrees, theme, i18n),
three `useQuery`s, and the group builders that assemble a few hundred rows.
`<Portal>` renders nothing while closed, so none of it was ever visible —
but all of it still ran. An in-flight update rewrites `$updateApply` on
every progress line, and each of those rebuilt the entire row set for a
surface nobody could see.

Split the body into `CommandPaletteBody`, mounted only while the palette is
on screen. A closed palette is now one store subscription. The body is keyed
by open count, so per-open state (search, sub-page) resets by remount and
the explicit close-reset effect goes away, and `mounted` lags `open` by the
150ms exit animation so Radix can still play `data-[state=closed]` instead
of the overlay vanishing.

Rows additionally move behind `useDeferredValue` in their own memo
component. Because that component mounts with the portal, the deferred
initial value applies per open: the first commit is the frame + input, and
the several-hundred-row list arrives in an interruptible follow-up render
rather than blocking the frame the keypress asked for. The empty state is
suppressed while rows are still pending so opening doesn't flash "no
results".

The `enabled: open` gates on the three queries are dropped — the component
only exists when open, so they are inherently lazy, and react-query still
serves a reopen from cache while revalidating.
2026-07-30 03:01:05 -05:00
..
perf
…
.gitignore
…
after-pack.mjs
…
assert-dist-built.mjs
…
assert-dist-built.test.mjs
…
assert-root-install.mjs
…
before-build.mjs
…
before-pack.mjs
…
before-pack.test.mjs
…
bundle-electron-main.mjs
…
click-session.mjs
…
dev-mock.mjs
…
dev-no-hmr.mjs
…
diag-code-live.mjs
…
diag-drag-churn.mjs
…
diag-drag-trace.mjs
…
diag-jump.mjs
…
diag-key-latency.mjs
…
diag-live-state.mjs
…
diag-overlay-ab.mjs
…
diag-overlay-churn.mjs
…
diag-overlay-full.mjs
…
diag-overlay-sweep.mjs
…
diag-real-loop.mjs
…
diag-ro-storm.mjs
…
diag-scroll-reset.mjs
…
diag-sidebar-dom.mjs
…
diag-switch-autopsy.mjs
…
diag-switch-trace.mjs
…
eval.mjs
…
gen-share-codes.ts
…
live-drive.mjs
…
notarize-artifact.mjs
…
notarize.mjs
…
patch-electron-builder-mac-binary.mjs
…
probe-command-palette.mjs
…
probe-model-picker.mjs
…
probe-renderer.mjs
…
probe-thread.mjs
…
profile-model-picker.mjs
…
profile-typing-lag.md
…
rebuild-native.mjs
…
reload-renderer.mjs
…
reload.mjs
…
run-electron-builder.mjs
…
set-exe-identity.mjs
…
stage-native-deps.mjs
…
stage-native-deps.test.mjs
…
test-desktop.mjs
…
utils.mjs
…
write-build-stamp.mjs
…
write-build-stamp.test.mjs
…