Skip to content

perf(core): trim per-keypress waste on the focus and state path - #56

Merged
chiefcll merged 1 commit into
mainfrom
perf/focus-path-allocations
Aug 29, 2026
Merged

perf(core): trim per-keypress waste on the focus and state path#56
chiefcll merged 1 commit into
mainfrom
perf/focus-path-allocations

Conversation

@chiefcll

Copy link
Copy Markdown
Contributor

What

Three behavior-preserving reductions on the path that runs for every focus change (so, every navigation keypress):

  • States.has() no longer allocates on prefixed lookups. It built a `$${state}` template string on every call to let unprefixed queries match (has('focus') matching '$focus'). The hot caller is updateFocusPath querying Config.focusStateKey, which is already $-prefixed, so that second lookup could only ever match a doubled prefix that nothing produces. A charCodeAt(0) check now short-circuits it; the allocation happens only when an unprefixed query misses the direct lookup.
  • updateFocusPath drops its per-press Set. The Set existed only to diff the previous focus path against the new one, never escaped, and the paths are a handful of elements. A linear indexOf scan does the same diff with no allocation or hashing.
  • _stateChanged skips the style-resolution branch when there is provably nothing to do. this._undoStyles is left as an empty array once a state style has been undone, and empty arrays are truthy, so the branch ran forever after that even when no style matched any active state. It now requires a non-empty undo list or a matching state style; every sub-case of the skipped branch assigns nothing.

Why

Keypress attribution work on the row-mount jank found the focus/state machinery is a small share of a press next to row construction inside Solid's batched key handler. These are the pieces of that machinery that were pure waste either way, aimed at allocation/GC pressure on TV-class devices.

Measured result, stated plainly

On a desktop browser these changes did not move the per-press benchmark numbers beyond run-to-run noise: an A/B/A sequence (6 benchmark runs per arm) showed environmental drift larger than any effect. They are strictly less work with identical observable behavior, so the recommendation is to gate this on a device benchmark run rather than take it as a claimed win. One semantic edge case to be aware of: a state literally named with a doubled prefix (e.g. '$$focus') would previously match a has('$focus') query and no longer does; nothing produces such a state.

Verification

  • pnpm test: 178/178 pass, repeated runs
  • pnpm tsc clean, pnpm lint clean
  • Behavior cross-check during benchmarking: _stateChanged call counts per press were bit-identical between baseline and this branch

🤖 Generated with Claude Code

Three behavior-preserving reductions on the path that runs for every
focus change:

- States.has() built a dollar-prefixed template string on every call to
  support unprefixed lookups (has('focus') matching '$focus'). The hot
  caller is updateFocusPath querying Config.focusStateKey, which is
  already prefixed, so the second lookup could only ever match a doubled
  prefix that nothing produces. A charCode check now short-circuits it,
  and the allocation happens only when an unprefixed query misses.

- updateFocusPath allocated a Set per focus change purely to diff the
  previous focus path against the new one. The paths are a handful of
  elements and the Set never escapes, so a linear indexOf scan does the
  same diff with no allocation or hashing.

- _stateChanged took the style-resolution branch whenever _undoStyles
  was set, including the empty array left behind once a state style has
  been undone (empty arrays are truthy). With nothing to undo and no
  style matching any active state the branch provably assigns nothing,
  so it is now skipped in that case.

Measured honestly: on a desktop browser these changes did not move the
per-press benchmark numbers beyond run-to-run noise; an A/B/A sequence
showed environmental drift larger than any effect. They are strictly
less work with identical observable behavior (178 tests pass unchanged),
and the allocation reduction targets GC pressure on TV-class devices, so
a device benchmark run is the gate on whether they actually help there.

Context: the keypress attribution work that motivated looking here found
the focus and state machinery is a small share of a press next to row
construction inside Solid's batched key handler. These are the pieces of
that machinery that were pure waste either way.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@chiefcll
chiefcll merged commit caf8bfd into main Aug 29, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant