From a87f0aeedb91a9172ea8acd63f1f3a4ace8bd9bc Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Sat, 11 Jul 2026 01:38:42 +0000 Subject: [PATCH] =?UTF-8?q?=E2=9A=A1=20Bolt:=20Optimize=20search=20filter?= =?UTF-8?q?=20by=20avoiding=20array=20allocations?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replaced the map/flatMap and array joining operations in the `searchMatchedNodeIds` useMemo hook in `frontend/src/App.tsx` with direct string concatenation. This eliminates heavy garbage collection pressure and multiple intermediate array allocations that occurred on every keystroke during ERD filtering. --- .Jules/bolt.md | 4 ++++ frontend/src/App.tsx | 18 ++++++------------ 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/.Jules/bolt.md b/.Jules/bolt.md index 9bb054fe..a7d2be75 100644 --- a/.Jules/bolt.md +++ b/.Jules/bolt.md @@ -1,3 +1,7 @@ ## 2025-06-27 - [Map Initialization Overhead] **Learning:** Initializing Maps with `new Map(array.map(...))` creates unnecessary intermediate arrays, consuming memory and triggering garbage collection overhead, especially noticeable when dealing with many nodes. **Action:** Use a `for...of` loop to directly `map.set()` elements rather than creating an intermediate array of tuples, especially in frequently executed or rendering paths. + +## 2025-06-27 - [High-Frequency Array Allocation in Render Loops] +**Learning:** Using `flatMap().join()` on arrays in a React render cycle (like high-frequency ERD search filtering inside `useMemo`) creates severe Garbage Collection pressure and performance bottlenecks compared to direct string concatenation due to intermediate array allocations. +**Action:** Use direct string concatenation with `+=` inside loops for heavy filtering operations to prevent excessive GC loads. diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index edaeeea0..3eabb7a2 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -194,19 +194,13 @@ export default function App() { const searchMatchedNodeIds = useMemo(() => { if (!normalizedNodeSearch) return new Set(); const matches = new Set(); + // ⚡ Bolt: Replace map/flatMap array allocation with direct string concatenation for high-frequency ERD search filtering to prevent severe GC pressure. for (const node of nodes) { - const haystack = [ - node.data.title, - node.data.comment ?? "", - ...node.data.columns.flatMap((column) => [ - column.column_name, - column.data_type, - column.column_comment ?? "", - ]), - ] - .join(" ") - .toLocaleLowerCase(); - if (haystack.includes(normalizedNodeSearch)) { + let haystack = `${node.data.title} ${node.data.comment ?? ""}`; + for (const column of node.data.columns) { + haystack += ` ${column.column_name} ${column.data_type} ${column.column_comment ?? ""}`; + } + if (haystack.toLocaleLowerCase().includes(normalizedNodeSearch)) { matches.add(node.id); } }