Repository navigation
perf(apollo-react): batch BaseNode's updateNodeInternals calls per React Flow store [ECS-2160] - #1572
Conversation
There was a problem hiding this comment.
🟢 Approval recommended
No active review issues are recorded for the change that batches node-internals updates per React Flow store.
No open issues 🎉
What changed in this PR
Reduces repeated React Flow store updates when mounting large diagrams by batching BaseNode internals updates per store.
Changes:
- Adds a microtask-based hook that collects and deduplicates node IDs separately for each store.
- Switches BaseNode to the batched hook and adds tests for batching, store isolation, StrictMode, and subsequent updates.
- Updates AgentCanvas test mocks to provide the store API required by the hook.
| File | Description |
|---|---|
packages/apollo-react/src/canvas/components/BaseNode/useBatchedUpdateNodeInternals.ts |
Adds per-store batching and ID deduplication. |
packages/apollo-react/src/canvas/components/BaseNode/useBatchedUpdateNodeInternals.test.tsx |
Tests batching, store isolation, and repeat updates. |
packages/apollo-react/src/canvas/components/BaseNode/BaseNode.tsx |
Uses the batched internals-update hook. |
packages/apollo-react/src/canvas/components/BaseNode/BaseNode.test.tsx |
Tests batched mounting and handle-change updates. |
packages/apollo-react/src/canvas/components/AgentCanvas/nodes/ResourceNode.test.tsx |
Adds the required store API mock. |
packages/apollo-react/src/canvas/components/AgentCanvas/nodes/AgentNode.test.tsx |
Adds the required store API mock. |
Review effort: Balanced
Dependency License Review
License distribution
Excluded packages
|
📊 Coverage + size by packagePer-package coverage and bundle size on this PR. New-line coverage = of the source lines this PR adds or changes, the % hit by tests.
"Coverage" is each package's own |
Storybook visual diffBaseline is the deployed main Storybook, so changes merged to main after this branch was last updated can also appear here. Logs Updated (PT): Nov 13, 2026, 08:24:07 AM |
…act Flow store [ECS-2160] Each BaseNode called updateNodeInternals on mount and React Flow turned every call into its own full-store update, so mounting N nodes cost N updates. BaseNode now queues its id and sends one update per store per task.
b4b1517 to
e09629e
Compare
ayushya
left a comment
There was a problem hiding this comment.
LGTM. Follow-up: SmartHandle still calls updateNodeInternals per handle on mount (prevPositionRef starts null), so useSmartHandles nodes keep the fan-out. Could reuse this hook there.
…chronous run [ECS-2160]
…ernals calls [ECS-2160] Both called updateNodeInternals per node from their own rAF, and microtasks run between rAF callbacks, so mounting N nodes still cost N store updates. They now call useBatchedUpdateNodeInternals from the effect; xyflow still measures in its rAF.
…hooks [ECS-2160] BaseNode renders SmartHandle, so SmartHandle importing from BaseNode/ was an upward edge. The hook now sits with the other shared canvas hooks; the public barrel is unchanged.
Each BaseNode called updateNodeInternals on mount and React Flow turned every call into its own full-store update, so a 585-node DMN diagram paid 585 store updates on open.
BaseNode now queues its id and sends one update per React Flow store per task, which cut the longest open task from 6.3 s to 1.25 s at 4x CPU with an identical end screenshot.
ECS-2160