Skip to content

Commit b6fe074

Browse files
authored
Merge pull request #305 from KxlSys/bolt-memoize-displaylist-3623682843127231969
⚡ Bolt: [performance improvement] Memoize displayList in ProjetsTab
2 parents ab67776 + 0c9a926 commit b6fe074

2 files changed

Lines changed: 8 additions & 5 deletions

File tree

.jules/bolt.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,6 @@
2121
## 2024-07-10 - O(n) Single Pass Data Aggregation
2222
**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.
2323
**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.
24-
## 2024-07-20 - Memoization of filtering logic
25-
**Learning:** In pages with heavily interactive inputs (like `AdminPage` with a search bar), performing O(N) array filtering synchronously within the component body causes the expensive calculation to block every re-render, compounding latency on keystrokes.
26-
**Action:** Wrap any O(N) filtering operations (e.g. `profiles.filter(...)`) in `React.useMemo` to ensure they only re-run when their specific dependencies (`profiles` or `searchQuery`) actually change, completely skipping the overhead on unrelated state updates.
24+
## 2024-03-24 - React Component State and List Derivation
25+
**Learning:** In components with highly interactive state (like a button triggering a local state change), deriving and formatting large lists inside the render body without memoization causes redundant O(N) object allocations on every render.
26+
**Action:** Always wrap data derivations (like mapping a raw dataset into UI-ready objects) inside a `useMemo` hook, ensuring the dependency array only includes variables that actually alter the list structure.

src/pages/matching-page.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -508,10 +508,13 @@ function ProjetsTab({
508508
}
509509
}, [user, interested]);
510510

511-
const displayList: { project: Project; score?: number; reasons?: string[] }[] =
512-
profile && projectMatches.length > 0
511+
// ⚡ Bolt: Memoize displayList to prevent O(N) object allocations on every render
512+
// (e.g. when 'interested' state changes after clicking the "Je suis intéressé" button).
513+
const displayList: { project: Project; score?: number; reasons?: string[] }[] = useMemo(() => {
514+
return profile && projectMatches.length > 0
513515
? projectMatches.map((m) => ({ project: m.project, score: m.score, reasons: m.reasons }))
514516
: projects.map((p) => ({ project: p }));
517+
}, [profile, projectMatches, projects]);
515518

516519
const visible = displayList.slice(0, visibleCount);
517520

0 commit comments

Comments
 (0)