react-tiny-virtual-list
react-tiny-virtual-list copied to clipboard
Perf
Hi @clauderic, thanks for this library!
I'm having a few performance issues which seem to be caused by onScroll triggering a setState which triggers a re-render. Here's a capture of scrolling through a list with a renderItem that only render simple <span>Hi</span>-items:

For reference, this is using the dev build of React 15.6.1, with 6x CPU slowdown.
This can be improved by adding the scroll listener as a passive event listener instead of using onScroll (AFAIK React does not support specifying events as passive using on*-props, so it must be set up in componentDidMount).
Additionally, to increase performance even more the VirtualList component could support a debounce-prop, which takes a number of milliseconds to debounce the handleScroll method with.
Would you be interested in a PR for this?
That would be amazing @bjoerge, currently I am debouncing but still, I am seeing performance drops.
PR submitted: #47
What if use requestAnimationFrame?
componentDidMount() {
let scrollTop = 0;
const step = () => {
if (scrollTop !== this.rootNode.scrollTop) {
scrollTop = this.rootNode.scrollTop;
this.handleScroll(scrollTop);
}
requestAnimationFrame(step);
};
this.rafId = requestAnimationFrame(step);
}
componentWillUnmount() { cancelAnimationFrame(this.rafId); }
react-sentinel as example
Any tips to have a 60fps framerate when scrolling?
what about to start using transform: translate3d instead of top?
what about to start using
transform: translate3dinstead of top?
In my experience testing this, using transform was actually slower.
@clauderic thanks! I'm just curious, in your perf test, did you use translate3d exact 3d option for transform or 2d (translatey)? From my understanding, translate3d should create one more virtual layer of context, which might help in terms of performance.
something like that
transform: translate3d(0px, %yourTopValue%px, 0px);
and change only %yourTopValue%?
For anyone who may stumble on it: this will cause any position:fixed element inside to behave like a position:absolute relative to the transformed element.
Why worrying about it? Because in a current project of mine I have columns with truncated overflowing content (with ellipsis).
To show full content I use a fixed positioned tooltip on the column with the full content once hovering over the column.
I had to find out that the virtual table was using the transform and that's why it was not possible.