From 842f17d6d97c52d1efac66a8dca298f6ca692a56 Mon Sep 17 00:00:00 2001 From: adamelmore <2363879+adamdottv@users.noreply.github.com> Date: Tue, 27 Jan 2026 14:51:34 -0600 Subject: perf(app): better memory management --- packages/app/src/pages/layout.tsx | 50 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 48 insertions(+), 2 deletions(-) (limited to 'packages/app/src/pages') diff --git a/packages/app/src/pages/layout.tsx b/packages/app/src/pages/layout.tsx index 82a3fa6c9..1328b96be 100644 --- a/packages/app/src/pages/layout.tsx +++ b/packages/app/src/pages/layout.tsx @@ -685,12 +685,34 @@ export default function Layout(props: ParentProps) { running: number } - const prefetchChunk = 600 + const prefetchChunk = 200 const prefetchConcurrency = 1 const prefetchPendingLimit = 6 const prefetchToken = { value: 0 } const prefetchQueues = new Map() + const PREFETCH_MAX_SESSIONS_PER_DIR = 10 + const prefetchedByDir = new Map>() + + const lruFor = (directory: string) => { + const existing = prefetchedByDir.get(directory) + if (existing) return existing + const created = new Map() + prefetchedByDir.set(directory, created) + return created + } + + const markPrefetched = (directory: string, sessionID: string) => { + const lru = lruFor(directory) + if (lru.has(sessionID)) lru.delete(sessionID) + lru.set(sessionID, true) + while (lru.size > PREFETCH_MAX_SESSIONS_PER_DIR) { + const oldest = lru.keys().next().value as string | undefined + if (!oldest) return + lru.delete(oldest) + } + } + createEffect(() => { params.dir globalSDK.url @@ -783,6 +805,11 @@ export default function Layout(props: ParentProps) { if (q.inflight.has(session.id)) return if (q.pendingSet.has(session.id)) return + const lru = lruFor(directory) + const known = lru.has(session.id) + if (!known && lru.size >= PREFETCH_MAX_SESSIONS_PER_DIR && priority !== "high") return + markPrefetched(directory, session.id) + if (priority === "high") q.pending.unshift(session.id) if (priority !== "high") q.pending.push(session.id) q.pendingSet.add(session.id) @@ -1669,6 +1696,22 @@ export default function Layout(props: ParentProps) { pendingRename: false, }) + const hoverPrefetch = { current: undefined as ReturnType | undefined } + const cancelHoverPrefetch = () => { + if (hoverPrefetch.current === undefined) return + clearTimeout(hoverPrefetch.current) + hoverPrefetch.current = undefined + } + const scheduleHoverPrefetch = () => { + if (hoverPrefetch.current !== undefined) return + hoverPrefetch.current = setTimeout(() => { + hoverPrefetch.current = undefined + prefetchSession(props.session) + }, 200) + } + + onCleanup(cancelHoverPrefetch) + const messageLabel = (message: Message) => { const parts = sessionStore.part[message.id] ?? [] const text = parts.find((part): part is TextPart => part?.type === "text" && !part.synthetic && !part.ignored) @@ -1679,7 +1722,10 @@ export default function Layout(props: ParentProps) { prefetchSession(props.session, "high")} + onPointerEnter={scheduleHoverPrefetch} + onPointerLeave={cancelHoverPrefetch} + onMouseEnter={scheduleHoverPrefetch} + onMouseLeave={cancelHoverPrefetch} onFocus={() => prefetchSession(props.session, "high")} onClick={() => { setState("hoverSession", undefined) -- cgit v1.2.3