From dd18b4c30b39d7214e37923c296180609b96ae4e Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Tue, 14 Jul 2026 14:23:44 +0000 Subject: [PATCH 1/4] =?UTF-8?q?=EC=84=B1=EB=8A=A5=20=EC=B5=9C=EC=A0=81?= =?UTF-8?q?=ED=99=94:=20GrooveMap=20maxTime=20=EA=B3=84=EC=82=B0=EC=9D=84?= =?UTF-8?q?=20reduce=EC=97=90=EC=84=9C=20for=20=EB=A3=A8=ED=94=84=EB=A1=9C?= =?UTF-8?q?=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .jules/bolt.md | 4 ++++ apps/desktop/src/features/workspace/GrooveMap.tsx | 9 ++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/.jules/bolt.md b/.jules/bolt.md index d54cf10f..b2b40a46 100644 --- a/.jules/bolt.md +++ b/.jules/bolt.md @@ -61,3 +61,7 @@ ## 2026-07-13 - Array.from mapping optimization **Learning:** Using `Array.from({ length: N }).map(...)` creates an intermediate array of `undefined` values which requires memory allocation and garbage collection, adding O(N) unnecessary overhead in frequently re-rendered UI components. **Action:** Use `Array.from({ length: N }, (_, index) => ...)` to map elements directly during array creation, avoiding intermediate allocations. + +## 2026-07-14 - Replace reduce with for loop for max calculation +**Learning:** Using `reduce()` with a callback function for simple iterations like finding a maximum adds significant overhead due to repeated function calls compared to a standard native loop. +**Action:** Replace `array.reduce()` with a simple `for` loop in performance-sensitive React renders for O(1) allocation overhead and faster execution times. diff --git a/apps/desktop/src/features/workspace/GrooveMap.tsx b/apps/desktop/src/features/workspace/GrooveMap.tsx index 2745d4d7..d11b0d00 100644 --- a/apps/desktop/src/features/workspace/GrooveMap.tsx +++ b/apps/desktop/src/features/workspace/GrooveMap.tsx @@ -17,7 +17,14 @@ function GrooveMapComponent({ notes, isLoading }: GrooveMapProps) { // Find max offset to determine timeline width const maxTime = useMemo(() => { - return renderedNotes.reduce((max, n) => Math.max(max, n.offset), 10); + // Performance: Avoid O(N) overhead of .reduce() callback allocations + let max = 10; + for (let i = 0; i < renderedNotes.length; i++) { + if (renderedNotes[i].offset > max) { + max = renderedNotes[i].offset; + } + } + return max; }, [renderedNotes]); // Unique pitches to determine vertical lanes (avoiding 88-key piano roll) From fe14245a65a8e37ff0f5fb23ce07597621061541 Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Tue, 14 Jul 2026 15:02:36 +0000 Subject: [PATCH 2/4] =?UTF-8?q?=EC=84=B1=EB=8A=A5=20=EC=B5=9C=EC=A0=81?= =?UTF-8?q?=ED=99=94:=20GrooveMap=20maxTime=20=EA=B3=84=EC=82=B0=EC=9D=84?= =?UTF-8?q?=20reduce=EC=97=90=EC=84=9C=20for=20=EB=A3=A8=ED=94=84=EB=A1=9C?= =?UTF-8?q?=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From 34f949a4739ea3b05122edf881ae1807c1667f4c Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Tue, 14 Jul 2026 15:41:22 +0000 Subject: [PATCH 3/4] =?UTF-8?q?=EC=84=B1=EB=8A=A5=20=EC=B5=9C=EC=A0=81?= =?UTF-8?q?=ED=99=94:=20GrooveMap=20maxTime=20=EA=B3=84=EC=82=B0=EC=9D=84?= =?UTF-8?q?=20reduce=EC=97=90=EC=84=9C=20for=20=EB=A3=A8=ED=94=84=EB=A1=9C?= =?UTF-8?q?=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From 9fb00cfe73f3d4620484f802d3e86c8f1e0bec97 Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Tue, 14 Jul 2026 16:19:24 +0000 Subject: [PATCH 4/4] =?UTF-8?q?=EC=84=B1=EB=8A=A5=20=EC=B5=9C=EC=A0=81?= =?UTF-8?q?=ED=99=94:=20GrooveMap=20maxTime=20=EA=B3=84=EC=82=B0=EC=9D=84?= =?UTF-8?q?=20reduce=EC=97=90=EC=84=9C=20for=20=EB=A3=A8=ED=94=84=EB=A1=9C?= =?UTF-8?q?=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit