From 814b4dfcf8303c04871da60dfb67068d39016a5a Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Fri, 3 Jul 2026 14:07:36 +0000 Subject: [PATCH] =?UTF-8?q?=E2=9A=A1=20Bolt:=20Improve=20table=20search=20?= =?UTF-8?q?performance?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Refactored `searchMatchedNodeIds` hook inside `App.tsx` to directly concatenate strings using an iterative loop (`+=`) instead of creating numerous temporary string arrays via `.flatMap` and spreading elements. This reduces memory allocation and garbage collection overhead during large diagram searches. --- .jules/bolt.md | 4 ++++ frontend/src/App.tsx | 19 +++++++------------ 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/.jules/bolt.md b/.jules/bolt.md index b45f9caa..8352e613 100644 --- a/.jules/bolt.md +++ b/.jules/bolt.md @@ -60,3 +60,7 @@ Optimized metric route processing to O(N) by creating a mapping of routes direct ## 2026-06-25 - Avoid Map allocations in frontend ERD loops and mutate asyncpg records in-place **Learning:** The frontend `snapshotToGraph` iterates over thousands of columns to generate the graph, so repeated lookups and redundant collection assignments increase GC pressure. Backend snapshot column dictionaries are freshly instantiated for the payload, so `add_column_examples` can safely fill missing fields in place. **Action:** Reuse existing collections while aggregating relational data, create `Map`/`Set` entries only on first use, and check for missing example fields before calling expensive inference helpers. + +## 2024-05-18 - [Optimize Array Spreads and FlatMap Operations During Frontend Search] +**Learning:** Using `Array.flatMap(...)` and array spread syntax (`...`) inside large iteration loops (like filtering a large subset of ERD nodes on the frontend) creates numerous temporary array allocations, leading to heavy Garbage Collection (GC) overhead and significantly decreasing UI performance. +**Action:** Replace `flatMap()` and array spreads with standard iterative loops and explicit value accumulations (e.g. string concatenation `+=`) to avoid intermediate allocations when filtering or constructing large composite properties on the fly. diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index e99700c5..62380aa0 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -182,18 +182,13 @@ export default function App() { if (!normalizedNodeSearch) return new Set(); const matches = new Set(); 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)) { + // ⚡ Bolt: Iterate through strings directly instead of array flatMap and join, which reduces GC and allocations + let haystack = node.data.title + " " + (node.data.comment ?? "") + " "; + for (let i = 0; i < node.data.columns.length; i++) { + const column = node.data.columns[i]; + haystack += column.column_name + " " + column.data_type + " " + (column.column_comment ?? "") + " "; + } + if (haystack.toLocaleLowerCase().includes(normalizedNodeSearch)) { matches.add(node.id); } }