# Performance notes ## Already in place - **Throttled node updates during drag** – `onNodesChange` merges changes and flushes at most once per animation frame (~60 fps) so dragging doesn’t trigger hundreds of re-renders per second. - **`nodeDragThreshold={1}`** – Avoids treating small pointer moves as drags and reduces noisy change events. - **Memoized React Flow props** – `nodeTypes`, `edgeTypes`, `defaultEdgeOptions`, and `flowContextValue` are memoized so their references don’t change every render. - **Custom `nodePropsAreEqual`** – Node components use `React.memo(..., nodePropsAreEqual)` so a node only re-renders when its own `id`, `data`, `width`, `height`, or `selected` change (e.g. dragging one node doesn’t force others to re-render when the library keeps their props reference stable). - **ConfigNode derived data** – `incomingEdges`, `incomingIds`, and `connected*` are wrapped in `useMemo` so they aren’t recomputed on every render. ## Further improvements you can try ### 1. Split context (medium effort) Right now every component that uses `useContext(FlowContext)` re-renders whenever `nodes` or `edges` change. You can split into: - **FlowDataContext** – `nodes`, `edges` (changes often). - **FlowActionsContext** – `setNodes`, `setEdges`, `isValidConnection`, etc. (stable). Components that only need actions (e.g. menus, buttons) subscribe to `FlowActionsContext` and won’t re-render on graph updates. ### 2. Avoid reading full `nodes`/`edges` where possible React Flow’s docs recommend not depending on the full `nodes`/`edges` arrays when you only need a small slice (e.g. “selected ids”). If you add features like selection state, keep that in a separate store or state (e.g. `selectedNodeIds`) and have components depend on that instead of filtering `nodes` everywhere. ### 3. Lighter node content - **CodeMirror** – Config and function nodes use CodeMirror; it’s heavy. Options: lazy-initialize the editor (mount only when the node is focused or visible), or use a plain `