Skip to content

Conversation

@waleedlatif1
Copy link
Collaborator

Summary

  • installed react scan, gated behind a FF
  • used react scan to identify rerendering issues and react issues

Type of Change

  • Performance
  • Performance

Testing

Tested manually

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

@vercel
Copy link

vercel bot commented Jan 18, 2026

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

1 Skipped Deployment
Project Deployment Review Updated (UTC)
docs Skipped Skipped Jan 18, 2026 3:14am

Request Review

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Jan 18, 2026

Greptile Summary

This PR implements comprehensive performance optimizations identified using React Scan, focusing on reducing unnecessary re-renders across the application through strategic use of Zustand selectors, memoization, and component architecture improvements.

Key Optimizations:

  • Zustand Store Pattern: Replaced whole-store subscriptions with selective getState() calls and targeted selectors using shallow and isEqual comparisons throughout hooks (use-undo-redo.ts, use-collaborative-workflow.ts, use-editor-block-properties.ts, use-depends-on-gate.ts)
  • Component Memoization: Added React.memo to frequently re-rendering components (Combobox, ToolbarItem, ShimmerOverlayText, OutputPanel)
  • Component Extraction: Isolated stateful logic into separate memoized components to prevent parent re-renders (e.g., OutputPanel from Terminal, ToolbarItem from Toolbar)
  • Operation Queue Refactor: Converted useOperationQueue hook to use getters instead of direct subscriptions, preventing components from re-rendering on every queue change
  • Dev Tool Integration: Added React Scan feature flag for ongoing performance monitoring (dev-only)

Impact:
The changes follow established React performance best practices and should significantly reduce unnecessary re-renders, particularly in complex workflow editing scenarios where Zustand store updates trigger cascading component updates.

Confidence Score: 5/5

  • This PR is safe to merge with minimal risk
  • The changes are focused, well-structured performance optimizations using standard React patterns (memo, selective Zustand subscriptions, shallow/deep equality checks). All modifications preserve existing functionality while reducing re-renders. The React Scan tool is properly gated behind a dev-only feature flag. No breaking changes or risky refactors present.
  • No files require special attention

Important Files Changed

Filename Overview
apps/sim/hooks/use-undo-redo.ts Replaced store subscriptions with selective state access and getState() calls to prevent unnecessary re-renders
apps/sim/hooks/use-collaborative-workflow.ts Replaced direct store references with getState() and added shallow comparison for diff store selectors
apps/sim/stores/operation-queue/store.ts Refactored useOperationQueue hook to use getters and selective subscriptions, preventing re-renders on queue changes
apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/hooks/use-editor-block-properties.ts Moved from useMemo to selective store subscriptions with shallow comparison for better performance
apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/hooks/use-depends-on-gate.ts Added isEqual deep comparison to prevent re-renders when dependency values haven't changed
apps/sim/components/emcn/components/combobox/combobox.tsx Wrapped Combobox component with memo to prevent unnecessary re-renders
apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/toolbar/toolbar.tsx Extracted ToolbarItem as memoized component and optimized trigger data caching

Sequence Diagram

sequenceDiagram
    participant User
    participant Component
    participant Hook
    participant ZustandStore
    participant ReactScan

    Note over ReactScan: Dev-only performance monitoring
    User->>ReactScan: Enable REACT_SCAN_ENABLED flag
    ReactScan-->>User: Loads react-scan script

    Note over Component,ZustandStore: Before: Whole-store subscriptions
    Component->>Hook: useUndoRedo()
    Hook->>ZustandStore: Subscribe to entire store
    ZustandStore-->>Hook: Full store state
    ZustandStore->>Component: Re-render on ANY store change
    
    Note over Component,ZustandStore: After: Selective subscriptions
    Component->>Hook: useUndoRedo()
    Hook->>ZustandStore: getState().push() (no subscription)
    ZustandStore-->>Hook: Execute action only
    Note over Component: No re-render triggered

    Note over Component,ZustandStore: Before: useMemo with dependencies
    Component->>Hook: useEditorBlockProperties()
    Hook->>ZustandStore: Subscribe to blocks, baselineBlocks
    ZustandStore->>Hook: Full blocks object
    Hook->>Hook: useMemo recalculates
    Hook-->>Component: Block properties
    
    Note over Component,ZustandStore: After: Selective with shallow
    Component->>Hook: useEditorBlockProperties()
    Hook->>ZustandStore: Select specific block props + shallow
    ZustandStore-->>Hook: Only {advancedMode, triggerMode}
    Hook-->>Component: Block properties (no re-render if equal)

    Note over Component,ZustandStore: Operation Queue optimization
    Component->>Hook: useOperationQueue()
    Hook->>ZustandStore: getState() for actions
    Hook->>ZustandStore: Subscribe only to hasOperationError
    ZustandStore->>Hook: queue/isProcessing via getters
    Note over Component: Re-renders only on error state changes

    Note over Component: Component memoization
    User->>Component: Props change
    Component->>Component: React.memo equality check
    alt Props unchanged
        Component-->>User: Skip re-render
    else Props changed
        Component->>Component: Re-render
        Component-->>User: Updated UI
    end
Loading

@waleedlatif1 waleedlatif1 merged commit 19a8dae into staging Jan 18, 2026
11 checks passed
@waleedlatif1 waleedlatif1 deleted the improvement/perf branch January 18, 2026 03:20
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.

2 participants