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 @@ -21,3 +21,7 @@
## 2024-07-10 - O(n) Single Pass Data Aggregation
**Learning:** Using chained array methods (e.g. `.map().filter()`, `.flatMap()`, and repeated `.filter()` over the same large list like `profiles`) leads to redundant O(n) passes over data and allocates unnecessary intermediate arrays. This blocks the main thread longer than necessary when calculating basic statistics like `uniqueCities`, `uniqueTechs`, or total counts.
**Action:** Consolidate statistical aggregations over large object arrays into a single O(n) `for` loop that updates multiple accumulators (like `Set` objects and primitive counters) in one pass, thereby improving performance and reducing memory overhead.

## 2024-07-18 - Component Map Memoization Pattern
**Learning:** In React components with highly interactive state (like buttons triggering local state changes such as `visibleCount`), mapping over raw datasets to create derived UI objects outside of a `useMemo` block leads to unnecessary O(N) object allocations and garbage collection on every render.
**Action:** When a component derives lists from props or state for rendering, wrap the mapping or filtering logic inside `useMemo` to cache the result, recalculating only when the underlying data changes, thereby freeing up the main thread from redundant object allocations.
11 changes: 8 additions & 3 deletions src/pages/matching-page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -508,12 +508,17 @@ function ProjetsTab({
}
}, [user, interested]);

const displayList: { project: Project; score?: number; reasons?: string[] }[] =
profile && projectMatches.length > 0
// ⚡ Bolt: Memoize the mapping logic to prevent O(N) object allocations on every render
// This avoids redundant work when local interactive states (like visibleCount or interested) change.
// Impact: Reduces main-thread blocking during re-renders by caching derived datasets.
const displayList: { project: Project; score?: number; reasons?: string[] }[] = useMemo(() => {
return profile && projectMatches.length > 0
? projectMatches.map((m) => ({ project: m.project, score: m.score, reasons: m.reasons }))
: projects.map((p) => ({ project: p }));
}, [profile, projectMatches, projects]);

const visible = displayList.slice(0, visibleCount);
// ⚡ Bolt: Memoize slicing to prevent re-instantiating the visible array on unrelated renders.
const visible = useMemo(() => displayList.slice(0, visibleCount), [displayList, visibleCount]);

if (isLoading) {
return (
Expand Down
Loading