Closed jonahallibone closed 2 years ago
Probably not relevant anymore, but I had the same issue with Chakra Table.
When I switched out every Chakra component to a 'normal' html element it rendered the rows much much faster.
@jsbeckr so we mananged to speed up the rendering quite a bit by changing some chakra setting on the popovers we used. Essentially they were being rerendered on each scroll, and we were able to prevent that. I still do have some concerns generally about rows with a lot of information because as of now each cell in a row still gets rerendered by default, even if remaining in view. I did memoize quite a bit of the table to enhance the performance out of the box.
Yeah, this has a lot to do with the components you are rendering and how many you are rendering. We'll keep improving the perf in react-virtual as much as we can, but can't control everything :)
Let us know if you run into more perf problems!
@jsbeckr This was spot on for me... Chakra made everything crazy slow. I guess I won't the using a components library after all, neither MUI, Chakra nor the one from Microsoft... at least not for tables
Does this slow row rendering issue apply to mui Components? For me, List items consist of the Mui timeline component with a bunch of nested Components (TimelineContent, Typography, Box, etc...)
Does this slow row rendering issue apply to mui Components? For me, List items consist of the Mui timeline component with a bunch of nested Components (TimelineContent, Typography, Box, etc...)
It appears so. I'm using a bunch of MUI components in my table (Checkbox, InputBase, Button, Typography, etc.) and can't figure out a way to fix the flickering without removing the MUI components.
I'm experiencing the same. Trying to migrate our custom table component from react virtuoso to tanstack virtual, because tanstack virtual is much more flexible. Performance was perfect in react virtuoso, but with tanstack virtual it is something like in your video.
I'm experiencing the same. Trying to migrate our custom table component from react virtuoso to tanstack virtual, because tanstack virtual is much more flexible. Performance was perfect in react virtuoso, but with tanstack virtual it is something like in your video.
@justasdev tanstack virtual is not doing any performance optimization while scrolling, so on every scroll everything is re-rendered, hard to say what is happening without reading the code, but try to pin point what is slow.
I have the exact same problem. Any guidance on how to handle rendering of MUI components?
Using pure html solves the problem, but that is unfortunately not a viable option as my app is deeply committed to MUI.
Anyone having issues with fixing their scroll flickering or lagging this has done wonders for me https://github.com/TanStack/virtual/issues/619#issuecomment-1969516091 . I should mention that this fix is for items have different dimensions i.e. dynamic scrolling where dimensions get generated while scrolling.
I solved the issue by wrapping every item in React.memo. This seems to mitigate unnecessary rerendering on scroll.
Here is a full example for dynamically sized items:
function VirtualList({ data }: { data: ListItemType[] }) { r
const virtualizer = useWindowVirtualizer({
count: data.length,
estimateSize: (i) => 1000,
overscan: 5,
})
const virtualItems = virtualizer.getVirtualItems()
return (
<div style={{
position: 'relative',
height: `${virtualizer.getTotalSize()}px`,
}}>
<div style={{
position: 'absolute',
top: 0,
left: 0,
width: '100%',
transform: `translateY(${virtualItems[0]?.start ?? 0}px)`,
}}>
{virtualItems.map( (virtualItem) => (
<div key={virtualItem.key}
ref={virtualizer.measureElement}
data-index={virtualItem.index}
>
<MemoizedListItem data={data[virtualItem.index]} />
</div>
))}
</div>
</div>
)
}
const MemoizedListItem = React.memo(({ data }: { data: ListItemType[] }) => {
return (
<div style={{paddingBottom: "30px"}}>
<ListItem data={data} />
</div>
)
})
@Torsteinws Good to hear that wrapping items in React.memo helped with the performance! Optimizing virtualized lists is definitely not a trivial task. Performance can be influenced by many factors beyond just code, like hardware capabilities and how quickly the browser can render elements. It's all about finding the right balance for your specific use case, but every bit of optimization helps overall.
Let me know if you come across any other findings!
It seems to me that the virtualizer is triggering a bunch of "unnecessary" rerenderings when scrolling. In my case, it caused me to feel a fair amount of friction when getting started with the library. Perhaps this is something the TanStack Virtual team can consider to address somehow?
If it is difficult to optimize the library in a way that fits all use cases, maybe it is possible to expose an option that somehow let you limit the amount of rerenders? If not, it would go a long way to just document best practices for having a performant virtual list.
Anyway, kudos for making a great api. The virtualizer feels ergonomic to use.
It seems to me that the virtualizer is triggering a bunch of "unnecessary" rerenderings when scrolling.
@Torsteinws This should be fixed alredy via https://github.com/TanStack/virtual/pull/806 if you can pin point where it happens in latest version, let's fix it.
I have been using version 3.10.8, so I should have this fix already.
I wonder if all items in a list are rerendered whenever virtualizer.getVirtualItems()
changes? If that is true, I can see why it can be expensive to scroll – especially if the items are a bit heavy to render or if the user scrolls a bit fast.
I wonder if all items in a list are rerendered whenever virtualizer.getVirtualItems() changes? If that is true, I can see why it can be expensive to scroll
No, we only re-render when range is changing or item position/size changes, you can easy test that by few of console logs.
I've been using the last few versions of
react-virtual
and i love the hook based api. However, I am getting some poor performance on row rendering. It's the classic empty and then flash to content on scroll. I thought perhaps this could be an issue with emotion (which i use for styling), however after stripping away all the emotion styles on the rows, it still performs quite slowly. I have broken everything up quite a bit and made sure that rerenders are localized only to components which have state changes. I've also played around with the overscan quite a bit, and can't seem to find a setting which renders smoothly. For the record, I am also using this withreact-table
. I am wondering if I am using the keys incorrectly somehow, or if this is just expected behavior. Below I've included some code snippets and a video:virtualized-table-row.js
virtualized-table-body.js
https://user-images.githubusercontent.com/8886318/119013404-f13b5e00-b964-11eb-887e-0c479e764ef0.mp4
Thanks again!