Description
In thread-list.tsx, formatRelativeTime(new Date(thread.updatedAt)) runs per thread item per render. This creates a new Date() inside the function for every item on every render. For long thread lists, this adds up.
File to change
surfsense_web/components/assistant-ui/thread-list.tsx (line 240, function at lines 280+)
Current code
<p className="truncate text-xs text-muted-foreground">
{formatRelativeTime(new Date(thread.updatedAt))}
</p>
function formatRelativeTime(date: Date): string {
const now = new Date(); // Created per call
const diffMs = now.getTime() - date.getTime();
// ...
}
What to do
Option A: Memoize per item using the already-memoized ThreadListItemComponent:
const relativeTime = useMemo(
() => formatRelativeTime(new Date(thread.updatedAt)),
[thread.updatedAt]
);
Option B: Share a single now timestamp across all items via a custom hook with a ticking timer (updates every minute):
function useNow(intervalMs = 60_000) {
const [now, setNow] = useState(() => new Date());
useEffect(() => {
const id = setInterval(() => setNow(new Date()), intervalMs);
return () => clearInterval(id);
}, [intervalMs]);
return now;
}
Option A is simpler and sufficient for a good first issue.
Acceptance criteria
formatRelativeTime is memoized per thread item
- Relative times still display correctly
- Thread list scrolling feels responsive
Description
In
thread-list.tsx,formatRelativeTime(new Date(thread.updatedAt))runs per thread item per render. This creates anew Date()inside the function for every item on every render. For long thread lists, this adds up.File to change
surfsense_web/components/assistant-ui/thread-list.tsx(line 240, function at lines 280+)Current code
What to do
Option A: Memoize per item using the already-memoized
ThreadListItemComponent:Option B: Share a single
nowtimestamp across all items via a custom hook with a ticking timer (updates every minute):Option A is simpler and sufficient for a good first issue.
Acceptance criteria
formatRelativeTimeis memoized per thread item