{event.title}
+{event.source}
+{event.mode}
+diff --git a/.jules/bolt.md b/.jules/bolt.md
index d5fcbd53e..ee4e66261 100644
--- a/.jules/bolt.md
+++ b/.jules/bolt.md
@@ -15,3 +15,7 @@
**Learning:** `dict.setdefault(key, []).append(value)` evaluates the empty-list default on every iteration, including when the key already exists. In grouping loops, `defaultdict(list)` avoids those transient unused list allocations while preserving insertion order.
**Action:** Use `defaultdict(list)` when missing keys are intentionally initialized with lists. Keep `setdefault` when its eager-default behavior or an ordinary `dict` is part of the required contract, and benchmark before claiming a material end-to-end improvement.
+## 2025-02-12 - Wrap array rendering loops with useMemo
+
+**Learning:** Mapping over arrays of properties inside a React functional component's render execution directly causes O(N) evaluations when unrelated state (like input queries or tab switches) updates the component.
+**Action:** Always wrap `.map()` calls that output elements in a `useMemo` block with exact prop array dependencies in large lists, especially if they are passed as props to avoid blocking the main thread on every re-render.
diff --git a/frontend/src/components/calendar/CalendarCandidateView.tsx b/frontend/src/components/calendar/CalendarCandidateView.tsx
index 35c681e06..7923a2277 100644
--- a/frontend/src/components/calendar/CalendarCandidateView.tsx
+++ b/frontend/src/components/calendar/CalendarCandidateView.tsx
@@ -1,3 +1,4 @@
+import { useMemo } from 'react';
import type { CalendarCandidateEvent } from './types';
type Props = {
@@ -5,22 +6,30 @@ type Props = {
};
export function CalendarCandidateView({ visibleCandidateEvents }: Props) {
+
+ // ⚡ Bolt: Wrap candidate events map in useMemo to prevent O(N) re-renders
+ // 🎯 Why: Mapping over event lists during unrelated parent renders (e.g. state changes) blocks the main thread.
+ const candidateEventsList = useMemo(() => (
+ <>
+ {visibleCandidateEvents.map((event) => (
+ {event.source} {event.mode}{event.title}
+
+ 표시 중인 캘린더 후보가 없습니다. +
+ )} + > + ), [visibleCandidateEvents]); return ({event.source}
-{event.mode}
-- 표시 중인 캘린더 후보가 없습니다. -
- )} + {candidateEventsList}{event.day}
+{event.source}
++ 표시 중인 캘린더 일정이 없습니다. +
+ )} + > + ), [visibleWeekEvents]); return ({event.day}
-{event.source}
-- 표시 중인 캘린더 일정이 없습니다. -
- )} + {weekEventsList}