My limited understanding of React is that it fails in (a), (b) and (c), and only limited measures can be applied to improve them. Re-creating the entire DOM on each update probably does not help. I have no information if (d) is possible with it.
I am using Angular.dart for a while now, and it can be used to get all of them in an optimal way.
Disclaimer: I'm working at Google.
(b) You can implement shouldComponentUpdate in order to have a quick way not to re-render a sub-tree if nothing changed.
(c) See (b) but we're also working on changing the internal representation of the virtual DOM to plain js objects that can be reused[1]. We were super worried about GC but it turns out that it hasn't been the bottleneck yet for our use cases.
(d) If you are writing pure React, all the actions are batched and actually, it's write-only, React almost never reads from the DOM. If you really need to read, you can do it in componentWillUpdate and write in componentDidUpdate. This will coordinate all the reads and write properly.
A really important part of React is that by default this is reasonably fast, but most importantly, when you have bottlenecks, you can improve performance without having to do drastic architecture changes.
(1) You can implement shouldComponentUpdate at specific points and get huge speedup. We've released a perf tool that tells you where are the most impactful places to[2]. If you are bold, you can go the route of using immutable data structures all over the place like Om/the elm example and you're not going to have to worry about it.
(2) At any point in time, you can skip React and go back to raw DOM operations for performance critical components. This is what Atom is doing and the rest of their UI is pure React.
[1] https://github.com/reactjs/react-future/blob/master/01%20-%2... [2] http://facebook.github.io/react/docs/perf.html#perf.printwas...
You seem to be an implementor, so two questions that maybe spare me looking at the source code :-)
1. How do you batch updates? 2. I am currently using an algorithm for longest increasing subsequences for avoiding superfluous dom insertions of children when diffing lists. I also make sure that the node containing the active element will not be removed from the tree during the diffing (if possible at all). Are you doing the same?
It's possible to change the batching boundaries via "Batching Strategies" but we haven't exposed/documented it properly yet. If you are interested, you can look at requestAnimationFrame batching strategy. https://github.com/petehunt/react-raf-batching
2. We cannot really use normal diff algorithms for list because elements are stateful and there is no good way for React to properly guess identity between old and new. We're pushing this to the developer via the `key` attribute.
See this article I wrote for a high level overview of how the diff algorithm is working: http://calendar.perfplanet.com/2013/diff/
2. I don't think we spend a lot of time trying to make this super optimal, but git grep ReactMultiChild to see what we do.
DOM reuse is not the same thing moving a DOM subtree to a different place. DOM reuse is e.g. getting an already-rendered table row, binding a new value to it, and modifying only the DOM properties in the complex DOM structure that actually did change. E.g. you modify only an Element.text deep in the first column, and a few other values in the other columns. Or maybe you need to do more, but all you do is delta. You don't just annotate a DOM structure with a key at row level, as it is closer to a hash of the DOM, not speaking of the data-dependent event handlers.
Calculating the DOM (virtual or not) is expensive, compared to not calculating at all. Creating a virtual DOM structure and not using it afterward creates GC pressure, compared to not creating at all. We are talking about optimizations in the millisecond range. A large table with complex components inside will reveal the impacts of these small things.
DOM coordination is not just making the DOM writes in one go. Complex components like to interact with each other, depending on their position and size on their page, and the changes in the underlying structure. They read calculated style values, and act upon those values, sometimes causing reflows. And if such things happen at scale, forced reflows may cripple the performance, and coordinating such changes may be more crucial than the framework you are choosing.
I am sure that people who are familiar with React may have their way get these stuff. I have looked at it, and I haven't seen it to happen automatically, while with Angular.dart, I get it without effort.
DOM node reuse is perhaps the central theme of React so it's odd that you bring this up as a criticism (see https://www.youtube.com/watch?v=1OeXsL5mr4g)
Calculating the virtual DOM does come with some processing and GC overhead, yes. But any system that tracks changes for you (data binding) comes with overhead and React makes the right set of tradeoffs for real apps (since it is a function of how large your render output is, not your underlying data model). React has about a 70% edge in CPU time on Angular in the "long list" class of benchmarks (which drops to a mere 40% with the Object.observe() performance unicorn). And steady state memory usage is almost always better with a virtual DOM approach since again it only tracks what you actually render which is usually smaller than your data model (https://www.youtube.com/watch?v=h3KksH8gfcQ).
DOM coordination boils down to non-interleaving of reads and writes to the DOM. React manages the writes for you which happen in one go. Components have a well-defined lifecycle which is also batched and are only allowed to read from the DOM during specific points in the lifecycle, which are coordinated system-wide. So out of the box if you follow the guidelines you will thrash the DOM much less (see http://blog.atom.io/2014/07/02/moving-atom-to-react.html)
<div class="row">
<div class="cell">
<div class="align-left">
Value.
</div>
</div>
</div>
I want to reach the following: <div class="row">
<div class="cell">
<div class="align-center">
Value B.
</div>
</div>
</div>
What do I need to do in React that on updating the underlying data, only the innermost Element's class attribute and innerText would change, and the rest of the DOM will be kept intact?The virtual DOM determines which mutations are necessary and performs only those, batched. It also reuses DOM nodes as appropriate. DOM nodes can even be keyed against data in the case that, between transitions, it isn't entirely clear which nodes correspond to which data.
(a) Using the key property, will give React a manner to determine likeness of elements
(b) Don't calculate the expensive things at render time, do them when loading or modifying state.
(c) Is related to a, but I haven't run into large problems with this personally.
(d) React does batch changes to an extent I believe.
Perhaps you meant virtual DOM here? (in any case, the actual DOM is not recreated on every update)