3 ms·
I'm not sure I would agree with that. First, from a technical perspective, a well-designed React app should only evaluate the minimal parts of the tree that ha
by richthegeek 11y ago
I'm not sure I would agree with that.
First, from a technical perspective, a well-designed React app should only evaluate the minimal parts of the tree that have changed. And React can do that easily with the PureRender mixin, or you can do it manually with the componentShouldUpdate method.
Secondly, from an empirical perspective, one of React's major selling points is that it renders many classes of DOM-based apps (and others) much more quickly than previous methods (e.g. jQuery, Angular) could achieve. React reduces the overall time spent performing CPU-intensive tasks, even if there is (_if_) there is an increase in CPU-time spent book-keeping.
Of course, it would be moot if the DOM wasn't so utterly dreadful from a performance perspective. But apparently it is fundamentally broken or it would have been fixed years ago.
- amelius 11y agoThe PureRender and componentShouldUpdate methods are "escapes" from the React philosophy, so I don't count them as being "React". They make the code more complicated because, with them, inconsistencies can easily arise. Making a simple local change to a list of N items, which would normally take O(1) energy, suddenly takes O(N) energy. Even with the PureRender and componentShouldUpdate methods, because React will traverse the complete list to determine which items should be changed (calling componentShouldUpdate for every item). I agree with you on the DOM. Its speed needs to improve. React offers a nice abstraction which may keep the code simple, but, as explained here, has problems of its own.
- richthegeek 11y agoHardly - they enforce the React philosophy more strictly. In an ideal system, Components receive props, modify internal state, and render idempotently based on these. The PureRender mixin is a way of saying "yes, this component conforms to the above constraints". Unfortunately, it's not always the case that the naive way of writing a Component will comply with the PureRender restrictions, so it's not enabled by default. It's not difficult, 99% of the time, to alter a Component to work properly with only minimal changes, and they aren't changes that make the Component code more confusing. ComponentShouldUpdate is a way of applying tree-trimming logic that React could not automatically know. Business logic and the like. When a Component implements componentShouldUpdate and returns false, it will prevent any children of that component being iterated in that loop. Ideally, componentShouldUpdate should just returning a Boolean value from state, rather than calculating it each time.
- amelius 11y ago> When a Component implements componentShouldUpdate and returns false, it will prevent any children of that component being iterated in that loop Yes, but when you alter 1 element of a list L, then L must be iterated (simply because it changed), so componentShouldUpdate() will return true for L. As a consequence, all elements of L will be checked. But you only changed one!
- richthegeek 11y agoI sort of see where you are coming from, but I can't see how it could be done any differently in an idealised system. If you change the elements in a set, you need to re-evaluate how that set is rendered. Wether you leave it to the elements to decide if they are to be altered, or have that logic in the set-handling code, the book-keeping (and related CPU time) still needs to occur? Either way, the proof is in the pudding: React is so insanely faster for this specific case than all other approaches.
- omphalos 11y agoWhat should happen is that we do incremental computation, sort of like what's described here [1]. You ought to be able to declaratively specify that such-and-such collection maps to such-and-such elements. If you change just one element in the collection, change tracking built into an incremental computation framework should cause that one element to update. Logically, there's really no need to review the entire collection if just one element changes. Certainly the Virtual DOM is one way to let you declaratively write to the DOM and not worry about change tracking yourself. But it's not the most efficient way. Unfortunately this sort of thing has never been implemented in JavaScript (that I can find) so currently the Virtual DOM is probably our least worst choice, at the moment. [1] https://blogs.janestreet.com/introducing-incremental/ https://blogs.janestreet.com/introducing-incremental/
- amelius 11y agoYes, this is also the approach I was thinking about. Perhaps it is time somebody at Facebook gets the chance to develop the javascript variant of this technique, as it is a far more "correct" way of approaching the problem, from a Computer Science standpoint.
- andy_ppp 11y agoAll the PureRenderMixin does is make sure that changes only update the DOM if state or props change. This is the ideal way you should be writing your React components anyway; I can't think of any edge cases where you don't want this (I'm sure they exist though)! I feel that this is scaremongering without real hard data. I'm happy to be proved wrong, should React be shown to be slower than an app that is updating the DOM with big blocks of innerHTML then reattaching event handlers, for example. With something like Redux and React you can connect only the parts of your tree that will change and react won't re-compare the whole tree as I understand it.
- spicyj 11y agoIf your shouldComponentUpdate always ends up returning true, then any time spent in that method is wasted, because you have to go update the component after that. And as React becomes more and more optimized, shouldComponentUpdate becomes less valuable. It is rare to have an expensive shouldComponentUpdate that returns true most of the time, but there is definitely a trade-off there that depends on the specifics of how data flows through your app. People like to put it on everything but we (React team) believe that it's probably best to put it in a few well-intentioned places. This tension is something we're actively thinking about.
- andy_ppp 11y agoI'm pretty certain you guys on the React team have lots of increasingly clever ideas to speed up the diffing, not limited to actual functions browser vendors could add in native code that could speed this stuff up. Generally React is 'very fast' to 'fast enough'. A very admirable situation to find yourselves in :-)
- woah 11y agoTry a good flux framework like Nuclear or Redux.