diff --git a/.jules/bolt.md b/.jules/bolt.md index 231af188b..f61d2f720 100644 --- a/.jules/bolt.md +++ b/.jules/bolt.md @@ -10,3 +10,6 @@ ## 2024-05-24 - Memoizing inline array maps **Learning:** Inline mapping of arrays inside JSX in large React components causes O(N) recalculation on every render. **Action:** Wrap inline JSX elements that map over arrays (e.g., lists of tasks) in a `useMemo` hook with specific dependencies. +## 2025-02-12 - Wrap email list array mapping in useMemo +**Learning:** In React components like `EmailList`, when long arrays (like `emails`) are mapped to JSX components directly inside the return block, any irrelevant state change (like a single keystroke updating `searchQuery`) forces a complete recalculation and re-render of all list items, blocking the main thread. +**Action:** Extract large array mapping logic into a `useMemo` block that only recalculates when its specific dependencies (e.g., `emails`, selection state) change, effectively preventing O(N) recalculations on unrelated state updates like user input. diff --git a/frontend/src/components/EmailList.tsx b/frontend/src/components/EmailList.tsx index 6dbb722ea..3a3e11a26 100644 --- a/frontend/src/components/EmailList.tsx +++ b/frontend/src/components/EmailList.tsx @@ -1,4 +1,4 @@ -import React, { useCallback, useEffect, useRef, useState, memo } from 'react'; +import React, { useCallback, useEffect, useRef, useState, memo, useMemo } from 'react'; import { apiClient } from '@/lib/api-client'; import { ScrollArea } from "@/components/ui/scroll-area"; import { Avatar, AvatarFallback } from "@/components/ui/avatar"; @@ -171,6 +171,33 @@ export function EmailList({ emptyTitle: '맥락 검색 결과가 없습니다', emptyBody: '맥락 검색어를 바꾸거나 메일 동기화 상태를 확인하세요.', }; + // ⚡ Bolt: Wrap email list in useMemo to prevent O(N) re-renders when search input changes + // 🎯 Why: Mapping over long lists of emails blocks the main thread during unrelated state updates like typing in the search box. + const emailListContent = useMemo(() => { + if (loading) { + return
{folderCopy.emptyTitle}
+{folderCopy.emptyBody}
+{folderCopy.emptyTitle}
-{folderCopy.emptyBody}
-