Avoid reconciliation, alternative component interface
See original GitHub issueHello. I want to ask a question about a way to avoid reconciliation process.
Today I can see the following process:
- Component wants to re-render.
- Component render method provides new virtual dom.
- Some react diff library tries to find some non-optimal way to morph old virtual dom into new one.
Please fix me if I am wrong, I am not familiar with react codebase.
I can see an information in docs:
you don’t have to worry about exactly what changes on every update
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:
// render is not defined
morph(component) {
if (...) {
component.append(<Item />);
} else {
(<Item />).prependTo(component.find({ key: '5' }));
}
}
Do you have any plans to implement it? Thank you. Please feel free to ask any questions.
Issue Analytics
- State:
- Created 5 years ago
- Comments:9 (6 by maintainers)

Top Related StackOverflow Question
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.
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
PureComponentor by caching React elements. Once you do that, you will likely find that skipping shallow reconciliation doesn’t bring you any measurable benefits.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.