diff --git a/.jules/bolt.md b/.jules/bolt.md new file mode 100644 index 0000000000..7094bd08a3 --- /dev/null +++ b/.jules/bolt.md @@ -0,0 +1,3 @@ +## 2025-04-28 - Optimize React list sorting +**Learning:** For optimal performance in React list rendering, prefer lexicographical string comparison (e.g., `b.updatedAt.localeCompare(a.updatedAt)`) over `new Date()` allocation when sorting by ISO 8601 timestamps, and always memoize the derived list to prevent O(n log n) object allocation overhead on re-renders. +**Action:** Always memoize derived lists and avoid `new Date()` object allocation in sorting functions for ISO 8601 strings. diff --git a/apps/app/src/components/ConversationsSidebar.tsx b/apps/app/src/components/ConversationsSidebar.tsx index 75d768bee2..1b1340eb68 100644 --- a/apps/app/src/components/ConversationsSidebar.tsx +++ b/apps/app/src/components/ConversationsSidebar.tsx @@ -2,7 +2,7 @@ * Conversations sidebar component — left sidebar with conversation list. */ -import { useEffect, useRef, useState } from "react"; +import { useEffect, useMemo, useRef, useState } from "react"; import { useApp } from "../AppContext"; interface ConversationsSidebarProps { @@ -54,11 +54,12 @@ export function ConversationsSidebar({ } }, [editingId]); - const sortedConversations = [...conversations].sort((a, b) => { - const aTime = new Date(a.updatedAt).getTime(); - const bTime = new Date(b.updatedAt).getTime(); - return bTime - aTime; - }); + // ⚡ Bolt: Memoize the sorting and use lexicographical string comparison for O(n log n) object allocation overhead on re-renders + const sortedConversations = useMemo(() => { + return [...conversations].sort((a, b) => + b.updatedAt.localeCompare(a.updatedAt), + ); + }, [conversations]); const handleDoubleClick = (conv: { id: string; title: string }) => { setEditingId(conv.id);