-
Notifications
You must be signed in to change notification settings - Fork 47.4k
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
Question about optimizing reconciliation on lists where only one/two children change #3309
Comments
I've run into this problem as well. I found that most of the time was spent in constructing the element descriptors in the vDOM for diffing. So the solution is to cache the descriptors and manage that cache. It's ugly, but it works. I believe React 0.14 will be much better at this because you can inline elements #3228 |
If @radubrehar is using shouldComponentUpdate correctly, he shouldn't be constructing a substantial number of descriptors for vdom diffing, right? cc @sebmarkbage cc @jordwalke sounds like a situation similar to your react-native situation where you wanted to tunnel updates, right? |
@JSFB you're still creating the elements before you go into the existing ones to run One of the things we've been working hard towards is the elimination of the need for calling createElement if it can be optimized away. That and a couple other ideas for optimizations are being discussed in #3228, #3227, #3226 What @jeffchan said should work, though it can get a bit unwieldy. Anther option is to start windowing. You may not actually need 1000 elements to be rendered if 900 of them aren't actually visible. This is also a fair amount of work (you have to start tracking scrolling and sizes) but definitely doable. We did that with fixed data table. |
I went with windowing and only rendering the visible rows (and some extra to top and bottom), and with this I managed to have an infinite number of rows in the list, with instant performance. I've read about the optimization ideas being discussed in the linked issues and they sound very cool. But in many (if not most) cases I will not be able to make all props as value types. I develop highly dynamic components, and most styles are configurable (eg: I have rowStyle; oddRowStyle, evenRowStyle for odd/even rows, etc) and as far as I've read value equality will not be applied in case where object maps are used (maybe tagging elements (as in #3227) will help here? I've tried caching element descriptors and that helps too, though windowing is a better solution in my scenario, since when the app re-renders I will only re-render a very limited set of children, while caching element descriptors is invalidated on props change. shouldComponentUpdate: function(){
...
},
shouldKeyedChildrenUpdate: function(){
...
return {
'a23d45': bool1,
'd75g63': bool2
} //only update children with the keys present in the object, and with the values set to true
} Just an idea that came quickly, not very polished, but maybe worth investigating? |
To fix this, I would suggest windowing (e.g. with react-virtualized) or, if you don't mind being lower level, caching React elements on your own. If a child is referentially equal React will skip reconciling it. |
I have a list with many children (>1000). When a change occurs in my scenario I have to setState on the list, which re-renders the list and all its children. I have optimized the children - they are keyed properly and also have shouldComponentUpdate implemented to be very very quick. When the change in the list occurs, I only have to update 1 or 2 children (I know exactly which ones), even if I may have hundreds/thousands of children. Yet it still takes a noticeable amount of time, since React reconciliation loops over all the children and checks if they should be updated or not.
Is there any special approach I can take that I may be unaware of?
The text was updated successfully, but these errors were encountered: