mirror of
https://github.com/simstudioai/sim.git
synced 2026-10-16 14:50:06 +08:00
* perf(mothership): virtualize chat transcript and isolate input from stream re-renders Long chats rendered every message into the DOM with no windowing — a custom rAF "progressive list" only smeared the mount cost across frames without capping it. At ~1000 messages this was 52k DOM nodes and a 21s main-thread block on open, and the input toolbar re-rendered on every streamed token. - Virtualize the message list with @tanstack/react-virtual using dynamic measureElement, stable per-row keys, and a tuned size estimate. Only the visible window mounts, so load cost is now flat regardless of transcript length. Remove the now-redundant useProgressiveList hook. - Memoize UserInput and stabilize its callbacks (useCallback in MothershipChat and home) so streaming ticks no longer re-render the entire input toolbar. - Keep the existing useAutoScroll for streaming stick-to-bottom (it reads the virtualizer's real scrollHeight) and add a per-chat scrollToIndex for initial positioning before paint. Measured on a cloned 1032-message chat: time-to-rendered 26.3s -> 1.7s, main-thread blocked 21.4s -> 0.8s, DOM nodes 52k -> 1.4k, typing-while- streaming p-max 104ms -> 26ms. Adds scripts/perf/ harness used to validate. * address review: pending-chat scroll, flash on tail unmount, empty-row gap, per-role estimate - Pending-chat initial scroll (Cursor, high): seed the scrolled-chat guard with a unique sentinel so a not-yet-persisted chat (undefined chatId) with messages still scrolls to bottom instead of being treated as already-scrolled. - Streaming-row flash (review of virtualization): pin the last row in the rendered window via rangeExtractor so scrolling it out of the overscan window and back mid-stream can't unmount/remount it and re-fire the reveal fade. - Empty assistant row gap (Greptile): move the row gap from the virtual-item wrapper into the row content so a null-rendering (finalised, empty) assistant turn collapses to zero height instead of leaving a pb-6 blank slot. - Per-role row-height estimate instead of a single blended constant, so the scrollbar drifts less as off-screen rows resolve. - Drop the scripts/perf harness from the PR. * fix(mothership): preserve user-row top spacing in virtualized layout Restoring pt-3/pt-2 on the user row keeps the exact inter-row rhythm from the old space-y-6 layout: assistant→user gaps stay 24+12px and user→assistant stay 24px, instead of becoming uniform when the gap moved to per-row pb. * fix(mothership): don't re-scroll when a pending chat persists its id The per-chat initial-scroll guard treated undefined→persisted-id as a chat switch and scrolled to the bottom again, yanking the viewport down if the user had scrolled up mid-stream. Treat that transition as the same conversation: adopt the id without re-scrolling. Genuine chat switches (id→different id) still re-scroll.