From b2891bbd7a5e4894782d406c705e9c2342b0ee15 Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Fri, 4 Sep 2026 01:36:15 +0000 Subject: [PATCH] =?UTF-8?q?=E2=9A=A1=20Bolt:=20[=EC=84=B1=EB=8A=A5=20?= =?UTF-8?q?=EA=B0=9C=EC=84=A0]=20=EC=9D=B4=EB=A9=94=EC=9D=BC=20=EB=A6=AC?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EB=A0=8C=EB=8D=94=EB=A7=81=20=EC=B5=9C?= =?UTF-8?q?=EC=A0=81=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .jules/bolt.md | 3 +++ frontend/src/components/EmailList.tsx | 22 +++++++++++++--------- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/.jules/bolt.md b/.jules/bolt.md index fa2deda3f..a8d8d4285 100644 --- a/.jules/bolt.md +++ b/.jules/bolt.md @@ -26,3 +26,6 @@ ## 2024-05-24 - [React Component Memoization] **Learning:** In React components like `WorkspaceHome`, when layout state or polling changes trigger parent re-renders, expensive child components like `EmailDetail` will also re-render unnecessarily if not memoized. **Action:** Always consider `React.memo` for heavy child components that rely on stable props (like IDs) when the parent component has frequent unrelated state updates. +## 2025-03-01 - Memoizing EmailList inline array map +**Learning:** Inline mapping of arrays inside JSX in the \`EmailList\` component causes O(N) recalculation on every render. +**Action:** Wrap inline JSX elements that map over emails in a \`useMemo\` hook with specific dependencies to prevent rendering bottlenecks. diff --git a/frontend/src/components/EmailList.tsx b/frontend/src/components/EmailList.tsx index 6dbb722ea..260e9e8d8 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"; @@ -173,6 +173,17 @@ export function EmailList({ }; const searchBusy = isSearching || loading; + const emailListNodes = useMemo(() => { + return emails.map((email: EmailItem) => ( + + )); + }, [emails, selectedEmailId, onSelectEmail]); + return (
@@ -259,14 +270,7 @@ export function EmailList({

{folderCopy.emptyBody}

) : ( - emails.map((email: EmailItem) => ( - - )) + emailListNodes )}