Skip to content

Conversation

@NateMateS
Copy link

@NateMateS NateMateS commented Apr 14, 2025

Context

With the growing context limits, the recent popularity of Orchestrator-based workflows, and UI updates that push larger messages into chat; it is increasingly becoming important that the users of Roo can reliably scroll through their conversations. Virtualization, admittedly as far as I know of the existing solutions myself, they do not handle dynamic elements that wildly differ in dimensions well. Usually, such applications of virtualization end in the scrollbar staggering, unexpectedly resizing as if content was being loaded and unloaded (because technically, it is); jumping; and even the entire chat flashing repeatedly. I also observed a lot of hacky methods used just to get Virtuoso into a semi-functional state. I do not consider it a good path towards optimization for a chat interface use-case.

I expect little loss of performance and low memory usage rise from the replacement of Virtuoso from the chat interface, and I've experienced no less performance than the Virtuoso implementation even on a chat that has a token total of ~80m.

The provided solution entirely eliminates the unreliable scrolling issues you experience with virtualization methods, and I consider possible further optimizations of such implementation the rational path forward.

Implementation

  1. Replaced react-virtuoso with Native Scrolling (webview-ui/src/components/chat/ChatView.tsx):

    • Removed the Virtuoso component and its associated logic.
    • Implemented scrolling using a standard div with overflow-y: scroll.
    • Updated scroll functions (scrollToBottomSmooth, scrollToBottomAuto), event handlers (handleScroll, handleWheel), and row expansion logic (toggleRowExpansion, handleRowHeightChange) to work with the native scroll container.
    • Messages are now rendered directly by mapping over the groupedMessages array within the scrollable div, instead of using Virtuoso's item renderer.
  2. Performance Optimizations:

    • Wrapped BrowserSessionRowContent in React.memo (webview-ui/src/components/chat/BrowserSessionRow.tsx).
    • Wrapped ChatRowContent in React.memo (webview-ui/src/components/chat/ChatRow.tsx).
    • Memoized the handleSuggestionClick callback function in ChatView.tsx using useCallback.
    • CSS contain: content was added for potential row rendering optimization.

Affected Files:

  • webview-ui/src/components/chat/BrowserSessionRow.tsx
  • webview-ui/src/components/chat/ChatRow.tsx
  • webview-ui/src/components/chat/ChatView.tsx

Impact:

  • The chat view now relies on standard browser scrolling instead of a virtualization library.
  • The use of React.memo should reduce unnecessary re-renders of chat rows, 'contain' should improve layout calculation, painting performance.
  • No observed performance loss, no observed memory rise.

Screenshots

--

How to Test

I suppose a good way to test the changes would be to A/B test on large chats, and try scrolling. Watch memory usage, and watch for performance issues. I've experienced little difference in both, personally - nothing I could even take note of.

As always, do test for any possible regressions in functionality, just in case.

Get in Touch

Discord: @dr.fumesb
I am present in the server.


Important

Replace chat virtualization with native scrolling and optimize chat row rendering using React.memo and CSS containment for improved performance.

  • Scrolling and Rendering:
    • Remove react-virtuoso virtualization from ChatView.tsx; replace with native scrollable div and manual scroll management.
    • Update scroll-to-bottom logic (scrollToBottomSmooth, scrollToBottomAuto), row expansion (toggleRowExpansion), and scroll event handling (handleScroll, handleWheel) to work with native scrolling.
    • Render chat messages by mapping over groupedMessages directly in ChatView.tsx.
    • Add CSS contain: content to chat row containers for layout/rendering optimization.
  • Performance Optimization:
    • Wrap ChatRowContent in React.memo in ChatRow.tsx to prevent unnecessary re-renders.
    • Wrap BrowserSessionRowContent in React.memo in BrowserSessionRow.tsx.
    • Memoize handleSuggestionClick in ChatView.tsx with useCallback.
  • Miscellaneous:
    • Remove all references to Virtuoso and related logic from ChatView.tsx.
    • Minor refactoring for clarity and performance in scroll/expansion logic.

This description was created by Ellipsis for 2af4ef5. It will automatically update as commits are pushed.

…ization rather than virtualization

- Removed all Virtuoso logic, replaced with normal stuff.
- Updated `BrowserSessionRowContent` and `ChatRowContent` components to use `memo`.
- Refactored scrolling logic in `ChatView`, ensuring smooth scrolling behavior and maintaining scroll position during row expansion.
- Adjusted event handling for scroll and wheel events to better manage auto-scroll functionality and user interactions.
@changeset-bot
Copy link

changeset-bot bot commented Apr 14, 2025

⚠️ No Changeset found

Latest commit: 028fc46

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@dosubot dosubot bot added size:XXL This PR changes 1000+ lines, ignoring generated files. enhancement New feature or request labels Apr 14, 2025
@cte
Copy link
Collaborator

cte commented Apr 14, 2025

Thanks @NateMateS - I agree with your assessment here. Do you mind taking a look at the test failure? I can help get this tested and over the finish line.

@NateMateS
Copy link
Author

Thanks @NateMateS - I agree with your assessment here. Do you mind taking a look at the test failure? I can help get this tested and over the finish line.

No problem. Yes, I looked at it just now. I think it's likely just a jsdom caused error that could be fixed with a simple check:

if (container && typeof container.scrollTo === "function") {

@hannesrudolph hannesrudolph moved this from New to PR [Pre Approval Review] in Roo Code Roadmap Apr 14, 2025
import debounce from "debounce"
import { useCallback, useEffect, useMemo, useRef, useState } from "react"
import { useDeepCompareEffect, useEvent, useMount } from "react-use"
import { Virtuoso, type VirtuosoHandle } from "react-virtuoso"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why you remove Virtuoso ?, this will make memory go up

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PR description explains the reasoning and also mentions:

No observed performance loss, no observed memory rise.

I want to spend some time profiling the memory though, just for my own edification.

@hannesrudolph hannesrudolph moved this from New to PR [Pre Approval Review] in Roo Code Roadmap May 20, 2025
@hannesrudolph hannesrudolph moved this from PR [Needs Review] to TEMP in Roo Code Roadmap May 26, 2025
@daniel-lxs daniel-lxs moved this from TEMP to PR [Needs Review] in Roo Code Roadmap May 26, 2025
@daniel-lxs
Copy link
Member

Hey @NateMateS, Thank you for your contribution, we apologize for taking so long to review this PR.
I'm curious, you mention no performance loss or memory usage rise, but does this implementation improves performance and lowers memory usage? Do you have any data about this that you can share?

This PR de-abstracts the scrolling logic of ChatView.tsx which basically means more code to maintain for Roo Code.
So I would like to know if the performance increase is worth having this extra scroll management code on our side.

I'll close this PR temporarily, as we now shifted to a issue-first workflow. This doesn't mean there's something wrong with your implementation.
If you'd like to revisit this please open an issue so we can discuss further!

We appreciate your patience and apologize again for the delay, I'm looking forward to improving our performance with your implementation!

@daniel-lxs daniel-lxs closed this May 31, 2025
@github-project-automation github-project-automation bot moved this from PR [Pre Approval Review] to Done in Roo Code Roadmap May 31, 2025
@github-project-automation github-project-automation bot moved this from PR [Needs Prelim Review] to Done in Roo Code Roadmap May 31, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request size:XXL This PR changes 1000+ lines, ignoring generated files.

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

4 participants