-
-
Notifications
You must be signed in to change notification settings - Fork 3.1k
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
overscanRowCount with a cell cache #476
Comments
I don't really understand what you're saying here. |
Sorry about that- it's possible that I didn't save the updated example. I am using the technique as described here: #448 to cache cells with the goal of avoiding unnecessary re-renders of rows. However, this cache does not seem to prevent re-renders for "overscanned" rows. In the example above, the render method of |
What do you consider to be an "extra render"?
That's because you're caching, so you avoid re-rendering once a row has already been rendered, no?
What do you define as "necessary"? By default, react-virtualized does not permanently cache cells. This is because (I think) cells are often dynamic and that would be a confusing default. It does reduce the number of cells that are rendered though, and it temporarily caches during scrolling, all of which means...overall performance is good enough that the lack of a permanent-cache isn't usually a problem.
I don't think you should ever set |
The Plnkr you linked to is preventing a cell from being rendered more than once. For example, check out this fork (that actually logs the index, so you can tell what's going on): https://plnkr.co/edit/H4btaSacFA5Fa6ft76Tu?p=preview |
I think what you were being confused by was due to the fact that you're overscanning by 30 in your example. This means that by default, 30 rows above and below. However when scrolling is in progress, react-virtualized shifts the overscanned rows in the direction being scrolled (so from 30 in each direction to 60 in the direction being scrolled). I'd guess you were seeing that, not expecting/understanding what was happening, and thinking it wa over-rendering. But yeah, 30 rows overscanned is mega overkill. :) I'd recommend 5 or 10 instead. |
Check out these slides from my recent presentation about react-virtualized: Step through (right arrow key) a few and it visualizes how overscanning works. :) I am pretty sure this issue is just a misunderstanding and so I'm going to close it. I'm happy to answer any follow-up questions you may have though! |
Thanks! I understand that explanation and the way overscanRowCount works, but I am still confused by the behavior in https://plnkr.co/edit/ebIVXCgOjM4XAddErRGi?p=preview. I would have expected that To provide an example, if the library caches rows |
To further clarify, if a user scroll from index 0 to index 1 and stops, I would expect that rows -15 to 31 should be cached. Then, if they scroll to index 2, we should only need to call render on row 32. I might just be very confused here... |
Ah, I understand. react-virtualized caches the creation of the cell (eg when your Put another way, react-virtualized isn't converting your component to an HTML string and caching that- that wouldn't be very React-like. :) So react-virtualized's caching doesn't prevent your component from re-rendering, but it does prevent unnecessarily re-instantiating your component many times. |
Ah I understand - thanks for explaining this :) Is there a suggested approach for caching the entire React tree of a row? In my case, the full render of a row can be expensive and I'd be willing to trade off memory for avoiding the extra computation, especially since overscanRow will call the |
You should definitely be using shallowCompare or extending
React.PureComponent to cut down on unnecessary, expensive renders. :)
|
Definitely :) The strange thing is that even with pure components, these children are still getting rerendered. I added a If I understand this correctly: https://facebook.github.io/react/docs/reconciliation.html these components should not be re-created at all, right? |
Ah, I see what you mean. Looking at the stack, Maybe this (recreating vs reusing) is to avoid confusion or potential sources of errors, or maybe it is because of some technical constraint. I need to make time to read through the underlying React source. Admittedly, this is not an area I know much about. Anyway, this suggests that it's probably not a good idea to try to permanently cache rows like this after all. Maybe a better approach would be to use the |
Relevant docs. Useful walkthrough here.
Returning JSX from a |
I see - that makes a lot of sense. Unless I'm misunderstanding, it seems like a potential fix here could be to change the behavior of |
Interesting suggestion. So you are suggesting that once rows shift ahead (or behind), they would stay that way unless the user started scrolling in the opposite direction? I wonder, is it really that expensive to instantiate your components (given that RV is only creating a few at a time)? |
Yep exactly- basically any behavior that doesn't suddenly change the active set of rendered rows would work for this use case. Though I appreciate the elegance of the balancing approach, it would be more suitable for my use case if RV always rendered In my use case, a single row render takes ~5ms - this means that we block the main thread rendering loop for |
What if it only ever did the predictive shift. Let's say overscan is 5. By default, RV renders 5 rows below (0 above) because users are most likely to start by scrolling down. If/when a user starts scrolling up, it shifts to render 5 above (0 below). In other words, it never renders above and below, and it never shifts/changes after scrolling stops. Thoughts? |
See PR #478 for discussion purposes. Would you like a build of this to test? I'd love to hear if it resolves your performance concerns. |
8.5.3 has been released. Hopefully this will address your overscan concerns. |
This is great!! Thanks again for your work on the library. |
Hi! Thanks for your work on this great library.
I am trying to use a cell cache along with overscan row count, and seeing extra renders from some children components. Here is an example: https://plnkr.co/edit/ebIVXCgOjM4XAddErRGi?p=preview
If you scroll very small amounts, notice that
rerendering
is logged 30 times on each change. This is far less than the number of times thatrowRenderer
is called.What I would expect is that the child component here is only re-rendered if necessary.
If I set
overscaneRowCount
to 0 I don't notice this behavior any more.The text was updated successfully, but these errors were encountered: