-
-
Notifications
You must be signed in to change notification settings - Fork 323
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Sluggish scroll on chromium based browsers when using many columns #860
Comments
Thanks for reporting this! I’ll check into the issue soon and see what can be done to improve the performance. Appreciate your patience! |
I'm facing the same problem |
In my use case, I could solve the scroll lag when I added the following to the table container: .container {
// ...
contain: 'paint',
will-change: 'transform',
} |
Setting the |
@piecyk It would be great if the Tanstack team could figure out why the CSS property is necessary? For me, the lagging only occurred after I revised and refactored our table components. So while it worked smoothly before, I now need this CSS property. That's strange. |
@MatchuPitchu That's interesting! It seems like something might have changed in Chrome recently. When I tested will-change: transform before, I didn’t notice much difference, but I’ll look into it again. Also, another CSS property that can help with virtualization issues is overflow-anchor: none; it can sometimes prevent unexpected scroll. I’ll experiment with these and let you know if I find anything useful! |
Thank you. During the test I noticed that the lagging in Edge was much less, even without the CSS property. This confirms that it could have something to do with Chrome. Do you mean or on the items? .container {
overflow-anchor: none;
} |
@MatchuPitchu directly on each item. |
@piecyk, I’m still experiencing sluggish scrolling when using the scrollbar. However, when I scroll using the Shift key combined with the arrow keys, the issue is significantly less noticeable. |
@soliyapintu facing same issue. @piecyk any solution? |
@piecyk my issues still persists, I have like 20 FPS on scrolling and elements load with delay |
@soliyapintu @vansh3476 @wwesolowski just to be on same page, basic combining react-table with react-virtual everyone experiencing these problems? |
@piecyk Unfortunately, yes. The scrolling behavior is smooth in Firefox and Edge, but it is sluggish in Chrome. Additionally, I have sticky columns on both the left and right sides. Does react-virtual provide any functionality to handle sticky columns? |
@piecyk Yes facing same problem. |
@piecyk tanstack table + tanstack virtual |
+1, extremely laggy scrolling on Chromium-based browsers, but it seems like there is no issue at all on Firefox-based ones. I can also confirm that putting the |
thank you the |
Hi! |
After extensive debugging and analysis, I observed that rendering simple text resolves the lagging issue. |
I significantly improved our table's performance by wrapping the virtualized absolute div children with React.memo. This optimization reduces unnecessary re-renders, enhancing efficiency. Before memoization :- #860 (comment) |
Tell me please. Do you have an example, how you did it? |
@YuesIt17 You need to take extra div above |
@soliyapintu can you provide any codesandbox example of fixing the issue? |
@piecyk Im have same problem. Hi, do you have any solutions? |
Thank you for all your thoughts @mio-moto . Do you have a full code example in which your optimizations can be better understood? I don't understand your |
@MatchuPitchu I have a working example here. Be sure to click the "Open preview in new tab" button, otherwise React Scan won't show up. With that, you can compare the performance on your machine. Speedyhttps://stackblitz.com/edit/tanstack-virtual-cdrheilm 20250208-1651-04.0482902.mp4(Watch the FPS counter) Sluggishhttps://stackblitz.com/edit/tanstack-virtual-k17x9n25 20250208-1650-22.1334472.mp4(Watch the FPS counter) Some notes
|
@mio-moto Wow, great work! Thanks for this detailed summary. Do you maybe have some ideas on how we can get some reliable numbers to test the performance and have something to compare?
Did you also test react 19 to see if it has a similarly big performance impact? We should definitely allow control over it. |
Sure, run your code in a cross-origin isolated environment for high precision dom timings and use this poorly implemented hook of mine: import { useEffect, useRef } from 'react'
export const useFps = (sampleCount: number) => {
const fps = useRef({
fps: 0,
max: 0,
min: 0,
frameTiming: 0,
samples: [] as number[],
})
useEffect(() => {
let lastTime = performance.now()
const updateFps = (now: number) => {
const delta = now - lastTime
lastTime = now
fps.current.samples.unshift(delta)
if (fps.current.samples.length > sampleCount) {
fps.current.samples.length = sampleCount
}
const frameTiming = fps.current.frameTiming * ((sampleCount - 1) / sampleCount) + delta / sampleCount
const frameRate = 1000 / fps.current.frameTiming
const sortedSamples = fps.current.samples.toSorted()
const worst = sortedSamples.slice(0, 4)
const best = sortedSamples.slice(sortedSamples.length - 6)
const max = 1000 / (best.reduce((a, b) => a + b, 0) / best.length)
const min = 1000 / (worst.reduce((a, b) => a + b) / worst.length)
fps.current = {
frameTiming,
fps: frameRate,
max: max,
min: min,
samples: fps.current.samples,
}
handler = requestAnimationFrame(updateFps)
}
let handler = requestAnimationFrame(updateFps)
return () => cancelAnimationFrame(handler)
}, [sampleCount])
return fps
} (there's some mishap about min/max frametiming, didn't care enough to fix it for looking at ballpark numbers.) I'm updating a div container every time the table re-renders, which is good enough, then scroll (programmatically) a screen worth of rows (or pull the scroll bar) and you see a stark contrast. I have a demonstration of that here - which is unfair to the case.
out.mp4
No, we've internally looked briefly at React19 and aren't in a hurry moving our code base to it, I've looked briefly at the changes to this specific problem and didn't notice anything major that prompted me to prioritize the move, either. (But my investigation was so shallow, that I would look at it again when I have migrated our code to the new table) |
@mio-moto I was playing around with your Speedy example, what about just limiting the overall re-rendering while scrolling, getting ~120fps on chrome while dragging. Something like https://stackblitz.com/edit/tanstack-virtual-qv5apjin |
I don't think that makes a great deal of a difference? I'm running a chrome with disabled vsync (create shortcut, add the parameters
Meanwhile your example clocks at roughly 200fps. The problem ultimately is to guesstimate well how the table should behave. I'd argue that you cannot, even in a high refreshrate environment, tell if you're emitting at 60 or 120fps new nodes, as long as the scrollbehaviour is smooth (which can be achieved in Chrome with a I think going forward, the trivial solution would be to be able to control how many children are emitted per frame (as part of the library) or going deeper into browser internals (with Edit: Maybe a way to benchmark different solutions would be to refresh every frame and not memoizing. I could come up with a relatively complex layout alike of what we're doing in prod to stress the layouter. |
Was thinking, if the rows are cheap to render, there should be less visible white space so the browser can keep up with rendering rather not rendering them.
Hmm, basic skipping of rendering, like in your Speedy example: on drag, you limit how many new rows are rendered. In some cases, we end up with 3 or 6 rows instead of 30, and these can even be outside the visible range. |
Yea, that's a few of the quarrels I have so far. The primary issue I've been really facing is coming up with good metrics when performance underflows a target. I'm today in the process of migrating most of what is necessary off of One of the problems I'm facing with the naive way without optimization is that the scroll-position of |
Describe the bug
Trying to render a Tanstack table with around 50 columns and I want to avoid using column virtualization and just stick with row virtualization. Seems like in Edge/Chrome I am getting pretty low FPS (~20 fps or so) once I start adding more and more columns. Weird thing is that this is even the case when I use a small dataset (200 rows) and overscan all of the items. On Firefox however I am getting good performance (~60fps).
Also I noticed that if I convert my code to useWindowVirtualizer() the scrolling performs way better, but unfortunately that doesn't suit my use case.
Your minimal, reproducible example
https://stackblitz.com/edit/tanstack-virtual-2gupur?file=src%2Fmain.tsx
Steps to reproduce
Expected behavior
How often does this bug happen?
Every time
Screenshots or Videos
No response
Platform
Windows 11, Edge v130
tanstack-virtual version
v3.10.8
TypeScript version
No response
Additional context
No response
Terms & Code of Conduct
The text was updated successfully, but these errors were encountered: