diff --git a/.jules/bolt.md b/.jules/bolt.md index fa2deda3f..419b09190 100644 --- a/.jules/bolt.md +++ b/.jules/bolt.md @@ -26,3 +26,7 @@ ## 2024-05-24 - [React Component Memoization] **Learning:** In React components like `WorkspaceHome`, when layout state or polling changes trigger parent re-renders, expensive child components like `EmailDetail` will also re-render unnecessarily if not memoized. **Action:** Always consider `React.memo` for heavy child components that rely on stable props (like IDs) when the parent component has frequent unrelated state updates. + +## 2026-08-30 - [Optimize NetworkGraph component rendering] +**Learning:** Heavy visualization components like `NetworkGraph` that instantiate complex third-party DOM-manipulating libraries (e.g., `vis-network`) can cause significant layout thrashing and costly re-instantiations if not memoized, particularly when parent components frequently re-render. +**Action:** Always wrap such heavy leaf components in `React.memo()` to prevent them from re-rendering unless their props change. diff --git a/frontend/src/components/NetworkGraph.tsx b/frontend/src/components/NetworkGraph.tsx index f9eb61c71..ac3f2d1ef 100644 --- a/frontend/src/components/NetworkGraph.tsx +++ b/frontend/src/components/NetworkGraph.tsx @@ -1,6 +1,6 @@ 'use client'; -import { useEffect, useId, useMemo, useRef, useState } from 'react'; +import { useEffect, useId, useMemo, useRef, useState, memo } from 'react'; import { Network } from 'vis-network'; interface Node { @@ -157,7 +157,9 @@ function describeEdge(edge: Edge, nodeMap: Map) { import { apiClient } from '@/lib/api-client'; -export default function NetworkGraph() { +// ⚡ Bolt: Wrapped in React.memo() to prevent expensive re-instantiations of the vis-network DOM graph +// when parent dashboard components re-render. +export default memo(function NetworkGraph() { const containerRef = useRef(null); const networkRef = useRef(null); const unavailableRelationshipDescriptionId = useId(); @@ -478,4 +480,4 @@ export default function NetworkGraph() { /> ); -} +});