-
Notifications
You must be signed in to change notification settings - Fork 46.9k
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
Avoid reconciliation, alternative component interface #13396
Comments
Before diving deeper — have you considered virtualizing your list (e.g. see https://react-window.now.sh/)? If reconciliation is a bottleneck it's a sign you might be rendering more items than necessary. |
Hello. I don't have any bottleneck today, but I don't want to receive it tomorrow.
It has complexity O(n) + reconciliation >= O(n), so complexity will be >= O(n). It couldn't be ok. createListComponent.js includes |
I think you're oversimplifying this. O(1) vs O(N) doesn't matter in any practical sense if we're talking about something that takes less than a millisecond either way. And if it takes more, N might be large enough that you need to worry about other things — such as the number of DOM nodes and complexity of calculating styles and painting — which often affects performance more significantly than React reconciliation. Reducing this to O(N) notation is missing the crucial details. The way you juxtapose O(1) and O(N) also doesn't acknowledge differences between deep and shallow reconciliation (which is very significant in practice). React doesn't let you skip the shallow reconciliation but it's a tiny slice of the time it would take to do a deep reconciliation. You can definitely skip the deep one — either through something like This is why I encourage you to ground this discussion in a practical example. In our experience, if O(N) vs O(1) starts mattering for reconciling e.g. list insertion, you're at a point where you have much more significant ways to optimize your app — either by a windowing technique or by bailing out of reconciling children (or by doing both). Hope this makes sense. |
Sorry, this was just a simple example. Let's consider stock exchange. We are managing huge list of stocks. Our complexity is the best available - Windowing technique won't be a generic solution. You couldn't select content (ctrl + A hotkey), use content search (ctrl + F hotkey), print page itself, etc and it won't be possible to fix it. All native browser functionality requires all dom elements sittings on their places. It is ok for country/state selection, autocompletes, etc. (when data is not important) |
I'd say something like stock exchange is pretty much the worst case you can pick for React — because everything is updating all the time. We don't optimize React for this use case because it’s relatively uncommon (most apps have significantly more “stable” UIs). For such a performance-critical piece it might make sense to completely skip React, and update text nodes manually using refs. You can still use normal React data flow for the rest of your app, but optimize this specific piece separately. But it’s hard to say whether that’s even necessary without a specific example.
Still, this is not a productive way to discuss a hypothetical performance problem. You can build a small stress test that demonstrates how many rows/columns you’re going to have, how many updates you have per second, and how deep the component tree is. I don’t think it would take you more than a few hours to build. You can artificially increase the rendering time for any component to simulate a deeper tree (if that’s what you're worried about). Then we can look at the example and discuss specific fixes you could do to get out of the “trap”. When it’s purely theoretical we can’t consider tradeoffs. In this case, if you never want to be “trapped”, the best way to ensure that is to not use any library. |
Seems this scenario is a little like the time-slicing demo which dan shows in his talk? But btw, why don't use three.js or d3.js or corresponding React library to do this rather than plain React? |
Sure, I will provide later a small example. I will investigate react code a bit to provide better performance measurement. I am wondering why there is only one interface for react component ( I saw issues about reconciliation #10382, #10703, etc. I think that react can provide better abstraction around this process and give user a chance to provide custom reconciliation or avoid it sometimes. |
Reconciliation is about more than just moving nodes around. Upcoming features like time slicing and suspense require a lot of internal coordination. Exposing even simple hooks to userland can leave us unable to implement some of these features efficiently for the common case. Ultimately you do have a custom mechanism at hand: use refs if you need to. You can have a component that does everything below imperatively. In fact you can even combine this approach with portals to continue declarative rendering below the parts you're trying to skip. |
Closing this as answered |
Hello. I want to ask a question about a way to avoid reconciliation process.
Today I can see the following process:
Please fix me if I am wrong, I am not familiar with react codebase.
I can see an information in docs:
But your solution has complexity about O(n) or even worse, so user should care about what changes sometimes. When user knows what changed he will be able to provide O(log n) or even O(1) solution.
For example I am working with huge data list and I am receiving information from websocket about how to morph my list: append/prepend, remove, swap items, etc. I don't want to render huge component list and run reconciliation process for each mutation. I can tell virtual dom how to morph efficiently.
Is there a way for user to provide morph method? I can imagine some api like:
Do you have any plans to implement it? Thank you. Please feel free to ask any questions.
The text was updated successfully, but these errors were encountered: