From 1534860a5eaa86aa929f4b5d9c113cc1d8c49612 Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Tue, 25 Aug 2026 01:46:33 +0000 Subject: [PATCH 1/4] =?UTF-8?q?=E2=9A=A1=20Bolt:=20=ED=95=B8=EB=93=A4=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=20=EC=8B=9C=20=EB=B0=B0=EC=97=B4=20=ED=95=A0?= =?UTF-8?q?=EB=8B=B9=20=EC=98=A4=EB=B2=84=ED=97=A4=EB=93=9C=20=EB=B0=A9?= =?UTF-8?q?=EC=A7=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .jules/bolt.md | 4 ++++ frontend/src/erd/handleUtils.ts | 16 ++++++++++++---- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/.jules/bolt.md b/.jules/bolt.md index f1a8c1466..916ff9401 100644 --- a/.jules/bolt.md +++ b/.jules/bolt.md @@ -77,3 +77,7 @@ Optimized metric route processing to O(N) by creating a mapping of routes direct ## 2024-07-13 - [Optimize Export Dictionary FK lookups] **Learning:** Found O(N * C * E) performance bottleneck in ERD export dictionaries due to repeated array searching with `edges.some()` inside a nested loop over nodes and columns. **Action:** Replace repeated linear array scans for edges by precomputing O(1) Set lookups of foreign key column handles per node before looping. + +## 2026-08-25 - [Avoid Array.from intermediate allocations in React hot paths] +**Learning:** Using `Array.from(string).join('-')` inside highly-invoked code paths like handle generation for ERD tables creates an intermediate array allocation for every column per node, causing significant garbage collection pressure during large graph renders. +**Action:** Replace `Array.from` with a simple string concatenation inside a `for...of` loop for hot paths to prevent intermediate array allocations and reduce GC overhead. diff --git a/frontend/src/erd/handleUtils.ts b/frontend/src/erd/handleUtils.ts index 054d5ab2a..24094c345 100644 --- a/frontend/src/erd/handleUtils.ts +++ b/frontend/src/erd/handleUtils.ts @@ -1,8 +1,16 @@ export function sanitizeHandleId(columnName: string): string { - const encoded = Array.from(columnName, (char) => { - // Array.from only yields non-empty Unicode scalars, so codePointAt(0) is defined. - return char.codePointAt(0)!.toString(16).padStart(4, '0') - }).join('-') + // ⚡ Bolt: Use a for...of loop instead of Array.from(columnName).join('-') + // to avoid allocating an intermediate array and reduce GC pressure for hot paths. + let encoded = '' + let isFirst = true + for (const char of columnName) { + if (!isFirst) { + encoded += '-' + } + // for...of over strings natively yields non-empty Unicode scalars, so codePointAt(0) is always defined. + encoded += char.codePointAt(0)!.toString(16).padStart(4, '0') + isFirst = false + } return `c-${encoded || 'empty'}` } From a1dafc6e9bf88ab64b1b40a6437ef3074497a9b8 Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Tue, 25 Aug 2026 02:29:18 +0000 Subject: [PATCH 2/4] =?UTF-8?q?=E2=9A=A1=20Bolt:=20=ED=95=B8=EB=93=A4=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=20=EC=8B=9C=20=EB=B0=B0=EC=97=B4=20=ED=95=A0?= =?UTF-8?q?=EB=8B=B9=20=EC=98=A4=EB=B2=84=ED=97=A4=EB=93=9C=20=EB=B0=A9?= =?UTF-8?q?=EC=A7=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From 6a6e9b1bedca3772184a7cbe30ee1aece45ddcbe Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Tue, 25 Aug 2026 03:34:52 +0000 Subject: [PATCH 3/4] =?UTF-8?q?=E2=9A=A1=20Bolt:=20=ED=95=B8=EB=93=A4=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=20=EC=8B=9C=20=EB=B0=B0=EC=97=B4=20=ED=95=A0?= =?UTF-8?q?=EB=8B=B9=20=EC=98=A4=EB=B2=84=ED=97=A4=EB=93=9C=20=EB=B0=A9?= =?UTF-8?q?=EC=A7=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From e3263f786d27829018ff3b317796a42d3c8ceab7 Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Tue, 25 Aug 2026 04:17:18 +0000 Subject: [PATCH 4/4] =?UTF-8?q?=E2=9A=A1=20Bolt:=20=ED=95=B8=EB=93=A4=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=20=EC=8B=9C=20=EB=B0=B0=EC=97=B4=20=ED=95=A0?= =?UTF-8?q?=EB=8B=B9=20=EC=98=A4=EB=B2=84=ED=97=A4=EB=93=9C=20=EB=B0=A9?= =?UTF-8?q?=EC=A7=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit