Skip to content

perf(popup-menu): stop aim-guard updates re-rendering every row - #584

Draft
kianbazza wants to merge 1 commit into
ui-641-compute-row-position-flags-once-per-order-changefrom
ui-642-stop-aim-guard-updates-re-rendering-every-row
Draft

kianbazza wants to merge 1 commit into
ui-641-compute-row-position-flags-once-per-order-changefrom
ui-642-stop-aim-guard-updates-re-rendering-every-row

Conversation

@kianbazza

@kianbazza kianbazza commented Oct 10, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

The aim guard context held four pieces of React state next to its refs. Every row consumes the context but only reads the refs, so each guard activate and clear re-rendered every row. The state now lives in its own context, read only by SubmenuTrigger.

 <AimGuardProvider>
-  <AimGuardCtx value={{ refs, activate, clear, aimGuardActive, guardedTriggerId, guardedDepth, guardedSubmenuSurfaceId }}>
+  <AimGuardCtx value={{ refs, activate, clear }}>                 // useAimGuard(): rows, Popup
+    <AimGuardStateCtx value={{ aimGuardActive, guardedTriggerId, guardedDepth, guardedSubmenuSurfaceId }}>
+                                                                  // useAimGuardState(): SubmenuTrigger

The refs context never changes while the provider is mounted. The logAimGuardEvents debug flag is read through a ref, so toggling it doesn't re-render rows either.

Evidence

row-renders.test.tsx › "keeps sibling rows still while the aim guard activates and clears": four items around a submenu, each wrapped in a <Profiler>. The pointer leaves the submenu trigger toward the submenu (guard activates), then moves inside the submenu (guard clears).

commits per sibling row     before: 2   after: 0
  • Before: AssertionError: Sibling 1: expected 6 to be 4
    After: passes

The existing aim guard tests (lifecycle, debug logging, continuous aim monitoring, safe triangle visualization) pass unchanged.

Merge Danger

Door: two-way

Blast Radius: small

Internal context only. Rows and Popup already read the guard through refs, so their behaviour is unchanged. SubmenuTrigger reads the same state values from a different context.

Closes UI-642

@vercel

vercel Bot commented Oct 10, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
ui-canary Ready Ready Preview Oct 10, 2026 11:33pm UTC

Request Review

@linear-code

linear-code Bot commented Oct 10, 2026

Copy link
Copy Markdown

UI-642

This branch was successfully deployed

1 active deployment
Preview – ui-canary — c2f1595c Deployed Oct 10, 2026 by vercel[bot]
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