Switch message timeline virtualization to Virtuoso#1933
Switch message timeline virtualization to Virtuoso#1933juliusmarminge wants to merge 2 commits intomainfrom
Conversation
- Replace TanStack virtualizer with react-virtuoso - Update timeline height measurement and virtualization tests
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Bugbot Autofix prepared a fix for the issue found in the latest run.
- ✅ Fixed: Stale height cache used on width-triggered Virtuoso remount
- Replaced the useEffect-based cache clear with React's synchronous 'update state during rendering' pattern (tracking prevVirtualizationWidthKey in state) so measuredRowHeightsById is cleared before the virtualizedRowHeightEstimates memo runs on the same render.
Or push these changes by commenting:
@cursor push 42d29fad02
Preview (42d29fad02)
diff --git a/apps/web/src/components/chat/MessagesTimeline.tsx b/apps/web/src/components/chat/MessagesTimeline.tsx
--- a/apps/web/src/components/chat/MessagesTimeline.tsx
+++ b/apps/web/src/components/chat/MessagesTimeline.tsx
@@ -278,6 +278,16 @@
() => (canVirtualize ? rows.slice(0, virtualizedRowCount) : []),
[canVirtualize, rows, virtualizedRowCount],
);
+
+ const virtualizationWidthKey =
+ timelineWidthPx === null ? "width:unknown" : `width:${Math.round(timelineWidthPx)}`;
+ const [prevVirtualizationWidthKey, setPrevVirtualizationWidthKey] =
+ useState(virtualizationWidthKey);
+ if (virtualizationWidthKey !== prevVirtualizationWidthKey) {
+ setPrevVirtualizationWidthKey(virtualizationWidthKey);
+ setMeasuredRowHeightsById({});
+ }
+
const virtualizedRowHeightEstimates = useMemo(
() =>
virtualizedRows.map((row) => {
@@ -300,12 +310,7 @@
],
);
const nonVirtualizedRows = canVirtualize ? rows.slice(virtualizedRowCount) : rows;
- const virtualizationWidthKey =
- timelineWidthPx === null ? "width:unknown" : `width:${Math.round(timelineWidthPx)}`;
const defaultVirtualizedRowHeight = virtualizedRowHeightEstimates[0];
- useEffect(() => {
- setMeasuredRowHeightsById({});
- }, [virtualizationWidthKey]);
const renderRowContent = (row: TimelineRow) => (
<divYou can send follow-ups to the cloud agent here.
Reviewed by Cursor Bugbot for commit 56dd6e1. Configure here.
ApprovabilityVerdict: Needs human review This PR replaces the virtualization library for the chat message timeline, swapping @tanstack/react-virtual for react-virtuoso. While the author wrote the original code and the change simplifies the implementation, this affects runtime scroll and rendering behavior in a core UI component, warranting human verification. You can customize Macroscope's approvability policy. Learn more. |
- Remove manual tail rendering and row height tracking - Use Virtuoso for the full timeline and keep autoscroll stable - Update virtualization harness expectations for appended rows


Summary
@tanstack/react-virtualtimeline implementation withreact-virtuosoinMessagesTimeline.react-virtuosoto the web package dependencies.Testing
bun fmtbun lintbun typecheckbun run testNote
Medium Risk
Medium risk because it replaces the core chat timeline virtualization/auto-scroll implementation; regressions could affect scroll position, rendering performance, or row height stability (especially with images and dynamic content).
Overview
Switches chat message timeline virtualization from
@tanstack/react-virtualtoreact-virtuoso.MessagesTimelinenow renders rows viaVirtuosowith per-row height estimates, a padded virtualization viewport, and newList/Itemwrappers that exposedata-virtual-row-*attributes.Auto-scroll behavior is simplified: instead of custom size-change scroll adjustment and snapshot reporting, the timeline uses
followOutputand triggersautoscrollToBottom()on image load only when the scroll container is near the bottom.Browser virtualization tests are updated to validate sizing and stability by reading the new virtual-row DOM attributes (and adjusting tolerances), and
react-virtuosois added to web dependencies.Reviewed by Cursor Bugbot for commit 366651f. Bugbot is set up for automated code reviews on this repo. Configure here.
Note
Replace TanStack Virtual with Virtuoso for message timeline virtualization
useVirtualizerfrom TanStack React Virtual withreact-virtuosoinMessagesTimeline, enabling full list virtualization for all rows.followOutputbehavior so the timeline auto-scrolls to the bottom when the user is already near the bottom, using aVirtuosoHandleref andisScrollContainerNearBottom.firstUnvirtualizedRowIndex,onVirtualizerSnapshot, and all snapshot/measurement wiring tied to the old virtualizer.data-virtual-row-sizeand assert size stability instead of transition semantics.onVirtualizerSnapshotis no longer accepted or invoked; tail rows are no longer force-rendered outside virtualization.Macroscope summarized 366651f.