How to NOT re-render list rows when scrolling?
See original GitHub issueAssume I have the following settings:
The container height: 400 The row height: 40
const virtual = useVirtual({
  size: 1000,
  parentRef,
  overscan: 20,
  estimateSize: useCallback(() => 40, [size]),
})
It seems that the container re-renders every visible row every time new row appears. This behavior maybe intentional but what if my row is heavyweight and the cost to re-render them is not trivial?
What I want to do is re-render only when the last row is visible.
In the above setup, I should see re-render happen once when i scroll to the 30th element, and insert next 20 element since overscan is 20.
Edit:
After play around with the source code, I see that setRange(prevRange => calculateRange(latestRef.current, prevRange)) actually cause the re-render every time index change.
I changed the if condition from
  if (!prevRange || prevRange.start !== start || prevRange.end !== end) {
    return {
      start: start,
      end: end
    };
  }
to
  if (!prevRange ||
    Math.abs(start - prevRange.start) > overscan - 1 ||
    Math.abs(end - prevRange.end) > overscan - 1
    ) {
    return {
      start: start,
      end: end
    };
  }
It reduce re-render from 999 to 50 when the data size is 1000 and overscan is 20.
Maybe we can allow developer to pass custom calculateRange function if they need to optimize performance? or improve calculateRange when overscan is used?
https://github.com/tannerlinsley/react-virtual/blob/master/src/index.js#L77
Issue Analytics
- State:
 - Created 3 years ago
 - Comments:9 (1 by maintainers)
 

Top Related StackOverflow Question
Some quick points to consider when things start to be slow
pointer-eventswhen scrolling.https://codesandbox.io/s/react-virtual-performance-list-pmyo2
Yep! Just prioritization. I’ll get to this issue soon.