Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .jules/bolt.md
Original file line number Diff line number Diff line change
Expand Up @@ -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-15 - Array reduce micro-optimizations in React

**Learning:** Replacing `array.reduce()` with a native `for` loop for finding maximum/minimum values in React components is generally considered a premature micro-optimization. Mapping or reducing over standard state arrays is rarely a bottleneck.
**Action:** Avoid micro-optimizations with no measurable impact. Always measure performance bottlenecks before optimizing array methods in UI components.
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
## [Unreleased]

### 성능 향상 (Performance)

- GrooveMap 컴포넌트의 렌더링 성능 최적화를 위해 `.reduce()` 및 `Math.max()` 호출을 네이티브 `for` 루프로 교체했습니다.
# Changelog

## [Unreleased]

### 성능 향상 (Performance)

- `GrooveMap` 컴포넌트의 렌더링 성능 최적화를 위해 `.reduce()` 및 `Math.max()` 호출을 네이티브 `for` 루프로 교체했습니다.

### Added

- Display the analyzed song tempo (BPM) as a badge in the rehearsal workspace.
Expand Down
9 changes: 8 additions & 1 deletion apps/desktop/src/features/workspace/GrooveMap.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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: Replace .reduce and Math.max with a native for loop to avoid callback allocation and overhead.
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)
Expand Down
Loading