Skip to content

fix(apollo-react): improve canvas overlay performance [MST-11141]#819

Merged
SreedharAvvari merged 3 commits into
mainfrom
codex/canvas-overlay-performance
Jun 16, 2026
Merged

fix(apollo-react): improve canvas overlay performance [MST-11141]#819
SreedharAvvari merged 3 commits into
mainfrom
codex/canvas-overlay-performance

Conversation

@SreedharAvvari

@SreedharAvvari SreedharAvvari commented Jun 14, 2026

Copy link
Copy Markdown
Contributor

Summary

This PR reduces unnecessary React/render work in the canvas overlay and loop-container paths during high-frequency interactions like dragging, resizing, multi-selecting, and geometry-only updates. The main target is avoidable component work around viewport portals, hidden overlays, loop chrome, sticky notes, and edge animation output.

What is optimized

  • Node viewport overlays subscribe only to geometry. NodeViewportOverlay now reads just x, y, width, and height from the React Flow store with a selector and shallow equality. That avoids re-rendering overlay portals when unrelated internal node fields change.
  • Hidden portal content stops mounting. HandleButton skips the viewport portal when neither the add button nor its label is visible. NodeToolbar also returns null for hidden toolbar instances that are rendered through the node overlay portal, so hidden toolbars do not keep portal wrappers and animation structure alive.
  • Loop success handle labels are removed. The loop success handle still exists for edge connectivity, but it no longer renders the visible Success label. This removes a portalized connected-handle label that was showing up during nested-loop drag profiling.
  • Loop shell chrome can bail out during drag. BodyFrame, ResizeControls, and ResizeCornerIndicators are memoized so static loop chrome does not rerender just because the loop shell rerenders. Resize hit targets remain mounted, so unselected loops can still be resized by hovering the resize controls.
  • Storybook-only static chrome can bail out. StoryInfoPanel is memoized so the story description panel does not rerender during canvas drag profiling.
  • Sticky notes skip position-only churn. StickyNoteNode now uses the position-insensitive node props comparator, so moving nodes does not force sticky note markdown, edit state, resize handles, toolbar config, and color picker UI to re-render unnecessarily.
  • Sticky note overlays render only when actionable. The sticky note toolbar and color picker overlay now share a single visibility guard and close during drag, resize, and multi-select states. That keeps overlay work out of interaction states where the controls are not usable.
  • Execution edge animations recompute only for in-progress edges. useExecutionEdge still applies status colors for all execution and validation states, but only calls getStatusAnimation when the edge status is InProgress. Completed, failed, and validation-colored edges no longer rebuild animation output on path-only geometry updates.
  • Loop child detection uses React Flow lookup state. Loop nodes now check parentLookup instead of scanning state.nodes to determine whether a loop has children, making that check a map lookup rather than a full node-list scan.
  • The shared node comparator is exported. nodePropsEqual is exported from canvas utils so other canvas nodes can reuse the same position-insensitive memoization path.

Demo

  • This PR primarily reduces avoidable re-renders from NodeViewportOverlay / viewport portal.
  • We still see expected re-renders from React Flow internals like NodeWrapper and EdgeWrapper.
  • CanvasEdge, SequenceEdge, EdgePath, and EdgeArrow still rerender when edge positions change because the SVG geometry has to move with the nodes.

Before vs After

image.2026-06-14.at.11.52.41.PM.mov
image.2026-06-14.at.11.55.18.PM.mov

Expected impact

  • Less React work while dragging, selecting, resizing, and moving around larger canvases.
  • Fewer hidden portal trees in the viewport overlay layer.
  • Less nested-loop drag churn from static loop chrome and connected handle labels.
  • Less animation recomputation for status-colored edges when only edge geometry changes.
  • Lower sticky note render cost during position updates and multi-node interactions.
  • Better scaling for loop-heavy canvases when checking child-node presence.

Validation

  • pnpm --filter @uipath/apollo-react exec vitest run src/canvas/utils/nodePropsEqual.test.tsx
  • pnpm --filter @uipath/apollo-react exec vitest run src/canvas/components/LoopNode/LoopNode.test.tsx
  • pnpm --filter @uipath/apollo-react exec tsc --noEmit --project tsconfig.json

Copilot AI review requested due to automatic review settings June 14, 2026 17:06
@github-actions

github-actions Bot commented Jun 14, 2026

Copy link
Copy Markdown
Contributor

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

Project Deployment Review Updated (PT)
apollo-design 🟢 Ready Preview, Logs Jun 15, 2026, 05:17:03 AM
apollo-docs 🟢 Ready Preview, Logs Jun 15, 2026, 05:17:03 AM
apollo-landing 🟢 Ready Preview, Logs Jun 15, 2026, 05:17:03 AM
apollo-vertex 🟢 Ready Preview, Logs Jun 15, 2026, 05:17:03 AM

@github-actions github-actions Bot added pkg:apollo-react size:M 30-99 changed lines. labels Jun 14, 2026
@SreedharAvvari SreedharAvvari changed the title [codex] Improve canvas overlay performance fix(apollo-react): improve canvas overlay performance Jun 14, 2026
@SreedharAvvari SreedharAvvari added the dev-packages Adds dev package publishing on pushes to this PR label Jun 14, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Dependency License Review

  • 1922 package(s) scanned
  • ✅ No license issues found
  • ⚠️ 2 package(s) excluded (see details below)
License distribution
License Packages
MIT 1692
ISC 89
Apache-2.0 55
BSD-3-Clause 27
BSD-2-Clause 23
BlueOak-1.0.0 8
MPL-2.0 4
MIT-0 3
CC0-1.0 3
MIT OR Apache-2.0 2
(MIT OR Apache-2.0) 2
Unlicense 2
LGPL-3.0-or-later 1
Python-2.0 1
CC-BY-4.0 1
(MPL-2.0 OR Apache-2.0) 1
Unknown 1
Artistic-2.0 1
(WTFPL OR MIT) 1
(BSD-2-Clause OR MIT OR Apache-2.0) 1
CC-BY-3.0 1
0BSD 1
(MIT OR CC0-1.0) 1
MIT AND ISC 1
Excluded packages
Package Version License Reason
@img/sharp-libvips-linux-x64 1.2.4 LGPL-3.0-or-later LGPL pre-built binary, not linked
khroma 2.1.0 Unknown MIT per GitHub repo, missing license field in package.json

@github-actions

github-actions Bot commented Jun 14, 2026

Copy link
Copy Markdown
Contributor

📦 Dev Packages

🧹 Dev packages cleaned up after PR close.

Last updated: 2026-06-16 08:34:13 PT

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR targets canvas performance during frequent geometry updates (dragging, multi-select, overlay/edge rendering) by reducing unnecessary renders and recomputations in node toolbars, viewport overlays, and animated edges.

Changes:

  • Avoid mounting node toolbar/overlay portal layers while dragging or when multiple nodes are selected.
  • Reduce expensive recomputation for edge animation output during geometry-only updates by memoizing only when animation is active.
  • Expand use of the position-insensitive node React.memo comparator (and export it via canvas utils) to cut down re-renders driven solely by absolute position updates.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated no comments.

Show a summary per file
File Description
packages/apollo-react/src/canvas/utils/index.ts Re-exports nodePropsEqual utilities from the canvas utils barrel.
packages/apollo-react/src/canvas/components/StickyNoteNode/StickyNoteNode.tsx Uses selection context + position-insensitive memo comparator; avoids rendering toolbar overlays in drag/multi-select states.
packages/apollo-react/src/canvas/components/NodeViewportOverlay.tsx Narrows store subscription to node geometry only (via useStore + shallow) instead of re-rendering on broader internal node changes.
packages/apollo-react/src/canvas/components/LoopNode/LoopNode.tsx Uses parentLookup to avoid O(n) scans; avoids mounting toolbar during drag/multi-select.
packages/apollo-react/src/canvas/components/Edges/shared/hooks/useExecutionEdge.ts Prevents recomputing edge animation output when the edge is not animating (geometry-only updates).
packages/apollo-react/src/canvas/components/ButtonHandle/HandleButton.tsx Skips rendering portal overlays when the button/label content is not visible.
packages/apollo-react/src/canvas/components/BaseNode/BaseNode.tsx Avoids mounting toolbar during drag/multi-select (rather than mounting and hiding).

@SreedharAvvari SreedharAvvari marked this pull request as ready for review June 14, 2026 17:37
Copilot AI review requested due to automatic review settings June 14, 2026 17:37

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated no new comments.

@snuziale

Copy link
Copy Markdown
Collaborator

@SreedharAvvari are you able to show a before vs. after with react-scan please.

@SreedharAvvari

Copy link
Copy Markdown
Contributor Author

@SreedharAvvari are you able to show a before vs. after with react-scan please.

Added, thanks!

@github-actions github-actions Bot added size:L 100-499 changed lines. and removed size:M 30-99 changed lines. labels Jun 15, 2026
@SreedharAvvari SreedharAvvari force-pushed the codex/canvas-overlay-performance branch from 55eceac to 874fe50 Compare June 15, 2026 12:11
@SreedharAvvari SreedharAvvari changed the title fix(apollo-react): improve canvas overlay performance fix(apollo-react): improve canvas overlay performance [MST-11141] Jun 15, 2026
@SreedharAvvari SreedharAvvari merged commit 23eb5fb into main Jun 16, 2026
42 of 43 checks passed
@SreedharAvvari SreedharAvvari deleted the codex/canvas-overlay-performance branch June 16, 2026 15:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dev-packages Adds dev package publishing on pushes to this PR pkg:apollo-react size:L 100-499 changed lines.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants