javascript - VirtualScroll rowRenderer method is called many times while scrolling - Stack Overflow

I have a react-virtualized's infinite scroll list, (Most of the setup is copied from this example)

I have a react-virtualized's infinite scroll list, (Most of the setup is copied from this example). I'm providing it with a rowRenderer function like the specs requires. this works fine if the rowRenderer function is very lightweight (i.e returns a very basic ponent as row). but the rendering of my RowComponent includes some Array.map over some properties. this shouldn't cause any problem except that the rowRenderer functions is being called tens or even hundreds of times while scrolling. this causes a performance issue, making the scroll not smooth enough. So far I tried:

  1. Caching my rowRenderer this works, but I don't like this solution as it may cause problems in the future.
  2. Make my RowComponent's render function pure and implement shouldComponentUpdate using react-addons-shallow-pare. this slightly improved the performance but not enough.

In this example, the rowRenderer function is also being called many times per scroll (no perf issues there as the function is very lightweight), which makes me believe this behavior is by design. so:
Is caching a good solution? any advice in how to sync it with my app's state (I use redux for state management)? is there something I missed in the docs that can reduce calls to rowRenderer (there's no reason for my rows to change while scrolling)?

I have a react-virtualized's infinite scroll list, (Most of the setup is copied from this example). I'm providing it with a rowRenderer function like the specs requires. this works fine if the rowRenderer function is very lightweight (i.e returns a very basic ponent as row). but the rendering of my RowComponent includes some Array.map over some properties. this shouldn't cause any problem except that the rowRenderer functions is being called tens or even hundreds of times while scrolling. this causes a performance issue, making the scroll not smooth enough. So far I tried:

  1. Caching my rowRenderer this works, but I don't like this solution as it may cause problems in the future.
  2. Make my RowComponent's render function pure and implement shouldComponentUpdate using react-addons-shallow-pare. this slightly improved the performance but not enough.

In this example, the rowRenderer function is also being called many times per scroll (no perf issues there as the function is very lightweight), which makes me believe this behavior is by design. so:
Is caching a good solution? any advice in how to sync it with my app's state (I use redux for state management)? is there something I missed in the docs that can reduce calls to rowRenderer (there's no reason for my rows to change while scrolling)?

Share Improve this question edited May 5, 2016 at 13:56 Guria 7,1331 gold badge19 silver badges19 bronze badges asked May 5, 2016 at 11:19 YakirNaYakirNa 5191 gold badge6 silver badges15 bronze badges 6
  • Clarification question: Are you concerned about the number of unique rows being rendered, or that a given row is rendered more than once? – bvaughn Commented May 5, 2016 at 15:42
  • I guess I am concerned more about that a given row is rendered more than once. although the final amount of calls to rowRenderer is the real pain, and can be reduced by reducing either as far as I understand... – YakirNa Commented May 5, 2016 at 16:00
  • For what it's worth I have a branch that caches a rendered row to avoid re-rendering it. I'm hoping that makes it into my v7 release. – bvaughn Commented May 7, 2016 at 1:44
  • By the way, would you be willing to share the source of your renderer with me? I'd like to learn more about what makes a renderer "slow". It might help me when perf-testing my caching branch. – bvaughn Commented May 7, 2016 at 1:49
  • sure. I'll try to take the code out to a gist or jsfiddle? – YakirNa Commented May 7, 2016 at 13:44
 |  Show 1 more ment

2 Answers 2

Reset to default 4

Author of react-virtualized here.

Your rowRenderer methods should be lightweight because, as you've found, they may be called rapidly when a user is scrolling. The good news is that- since browsers manage scrolling in a separate thread from the UI, this usually doesn't cause any performance problems. If anything, you may notice some empty/white space at the edge of the list in the direction you're scrolling- indicating that your renderers aren't able to keep up with the user's scrolling speed.

One caveat to be aware of though is that if you attach touch or wheel event handlers to a react-virtualized ponent or one of its DOM ancestors, this will force the browser to scroll in the main/UI thread. That can definitely cause slowness.

I'm currently in the middle of a major update (version 7) which, among other things, will passed named arguments to user-functions like rowRenderer. This will enable me to pass meta information (like whether or not the list is currently scrolling) which could enable you to defer "heavy" logic while a scroll is in progress. Unfortunately this isn't possible in version 6 unless you're willing to use a timeout as doron-zavelevsky mentions.

Edit: You may be happy to learn that with this mit cell caching has made its way into the uping version 7 release.

From my experience with this library (I'm not using the latest version though) - this is by design. It makes sense - in order to avoid rendering all the list at once - and to allow you infinite scroll - it asks you every time to render the currently viewed item. Your goal is to optimize the render function - as you yourself mentioned. One more thing that can improve your overall experience is to check and see if your item contains some plex code in its ponentDidMount life-cycle method - or any other code that runs post-render. If that's the case - you can optimize for fast scrolling by delaying these calculations with a timeout - and only let them run if the ponent is still mounted when the timeout passes.

Consider the case that you fast scroll over items to get to the bottom - there's no sense in fully populating all the items you scroll past on the way there. So you return the render result as fast as you can - and inside the item you wait ~200ms - and then you check whether the ponent is still mounted and do the real work.

Since isMounted is obsolete you can simply set a variable to true during ponentDidMount and back to false of ponentWillUnmount.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745197425a4616163.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信