feat(workflow): resolve canvas re-rendering and logs perf issues#3844
feat(workflow): resolve canvas re-rendering and logs perf issues#3844adithyaakrishna wants to merge 6 commits intosimstudioai:stagingfrom
Conversation
PR SummaryMedium Risk Overview Terminal/output changes: Workflow canvas changes: introduces new hooks ( Written by Cursor Bugbot for commit 0ec73b0. This will update automatically on new commits. Configure here. |
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
apps/sim/app/workspace/[workspaceId]/w/[workflowId]/hooks/use-node-derivation.ts
Outdated
Show resolved
Hide resolved
...app/workspace/[workspaceId]/w/[workflowId]/components/terminal/hooks/use-terminal-filters.ts
Outdated
Show resolved
Hide resolved
Greptile SummaryThis PR addresses severe UI lag and cascading re-renders on the workflow canvas during parallel loop execution through three complementary strategies: (1) store-level granularity — replacing the full The large Key findings:
Confidence Score: 5/5Safe to merge — all remaining findings are P2 quality/optimisation notes that do not affect correctness or produce observable regressions. The core performance objectives are implemented correctly. Both flagged issues are pre-existing behaviour or safe-in-practice design choices; neither blocks merge. use-node-derivation.ts (blocksStructureHash dep optimisation); terminal.tsx (VirtualEntryNodeRow callback subscription) Important Files Changed
Sequence DiagramsequenceDiagram
participant ES as ExecutionStore
participant UIBP as useIsBlockPending(blockId)
participant UBRS as useBlockRunStatus(blockId)
participant BV as useBlockVisual
participant WB as WorkflowBlock (memo)
participant SS as SignalStore (useSyncExternalStore)
participant VER as VirtualEntryNodeRow (memo)
Note over ES: Block becomes active during parallel loop
ES->>UIBP: activeBlockIds updated
UIBP->>WB: re-render only this block
ES->>UBRS: lastRunPath updated for blockId
UBRS->>BV: runPathStatus changed
BV->>WB: ring styles updated
Note over ES: New console entry arrives
ES->>SS: signalStore.update(selectedId, expandedNodes, ...)
SS->>VER: useSyncExternalStore notifies (if selectedId/expandedNodes changed)
VER->>VER: re-render only affected rows
Note over ES: Other blocks unchanged
ES--xWB: NO re-render (per-block selector)
ES--xVER: NO re-render (unchanged selectedId/expandedNodes)
Reviews (2): Last reviewed commit: "chore: fix review changes" | Re-trigger Greptile |
apps/sim/app/workspace/[workspaceId]/w/[workflowId]/hooks/use-node-derivation.ts
Outdated
Show resolved
Hide resolved
|
@adithyaakrishna is attempting to deploy a commit to the Sim Team on Vercel. A member of the Team first needs to authorize it. |
.../sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/workflow-block.tsx
Outdated
Show resolved
Hide resolved
apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/terminal/terminal.tsx
Outdated
Show resolved
Hide resolved
apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/terminal/terminal.tsx
Show resolved
Hide resolved
|
@greptile review |
apps/sim/app/workspace/[workspaceId]/w/[workflowId]/utils/workflow-canvas-helpers.ts
Outdated
Show resolved
Hide resolved
apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/terminal/terminal.tsx
Show resolved
Hide resolved
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
| if (prevDataJsonRef.current !== newJson) { | ||
| prevDataJsonRef.current = newJson | ||
| setExpandedPaths(computeInitialPaths(data, isError)) | ||
| } |
There was a problem hiding this comment.
Unguarded JSON.stringify can throw on non-serializable data
Medium Severity
The new deep-equality check calls JSON.stringify(data) without a try-catch. If data contains circular references, BigInt values, or other non-JSON-serializable structures, this will throw an unhandled error and crash the structured output component. The previous code only compared by reference (prevDataRef.current !== data), which can never throw.
Additional Locations (1)
| dataRef.current = { rows } | ||
|
|
||
| const signalStoreRef = useRef(createRowSignalStore()) | ||
| signalStoreRef.current.update(selectedEntryId, expandedNodes, onSelectEntry, onToggleNode) |
There was a problem hiding this comment.
Signal store mutated during React render phase
Low Severity
signalStoreRef.current.update() is called during the render of TerminalLogsPane, not inside a useEffect. When the update detects changes, it synchronously fires all useSyncExternalStore listeners. This is a side effect during render, violating React's requirement that rendering be pure. It can cause issues in React Strict Mode (double invocation) and is fragile in concurrent rendering scenarios.


Summary
Fixes severe UI lag and re-rendering issues on the workflow page during parallel loop execution. The canvas, output panel, input tab, and terminal logs all suffered from cascading re-renders when many iterations ran simultaneously.
Type of Change
Testing
Checklist