You can't decrease time by 4000%. If you decrease by 100%, it's all gone (you can make something 40x faster, in which case it's now takes 2.5% of the original, so decreasing time 97.5%).
That helps, but component rendering can still take a long time, so if you have a lot of them you are going to want to take advantage of shouldComponentUpdate
This article can be summarized by "I implemented shouldComponentUpdate and stopped mutating my data to make that easy". It's a good write up of what is otherwise standard Reactjs practice, but it really doesn't warrant all the 4000% nonsense. "How I used shouldComponentUpdate to make React rendering faster" would've been a more obvious title.
The amazing thing (to me) is that as a ClojureScript user I struggled to understand where the performance problems described in this article came from. If you use ClojureScript with React, by default you get no such issues, because of immutable data structures.
shouldComponentUpdate: function(nextProps) {
return nextProps.tile.active !== this.props.tile.active;
}
"That means that nextProps.tile and this.props.tile are pointing at the exact same object, so they will always be equal."
If this is the case, shouldComponentUpdate would always return false and he should not see any of the components update. But he's seeing ALL of them update.
Because of its fancy virtual DOM, it does far less page manipulation than, say, Angular.
This is not really true. Angular does dirty checking on the model backing the DOM, while libraries like Mithril or React do it on a virtual DOM that you have to recreate from scratch on every frame.
If you want to really avoid DOM hangups, just use a library like GreenSock or FastDOM.
creating a virtual DOM != manipulation. All fastDOM does is ensure that all DOM writes happen at once, not that you're doing the minimum number of operations necessary. And greensock is an animation library, so I'm not sure how it relates to the problem in question.
Right, that's all you need to make sure there isn't thrashing. You can write to the DOM as much as you want during an animation frame, and only the latest write will be used. Provided you don't also read from it, which triggers a layout.
Other than this, all these frameworks essentially do dirty checking when it comes time to render. Angular does it on the model, and React / Mithril do it on a virtual DOM, leaving it up to you how you update the virtual DOM. Usually they want you to recreate the entire DOM from the beginning, and then try to optimize the tree walk using immutability.
In any case, you don't need anything nearly as fancy as this. You can just subscribe to events when your model changes, and use FastDOM to update your DOM on those events. It is more efficient as it does only the minimum work necessary, instead of dirty-checking, albeit sometimes it may draw the same HTML in the same place.
The real benefit of React is not in virtual DOM, even though virtual DOM enable the real benefit to be feasible.
It's in enabling developer to think only in "recreating the whole DOM".
Subscribing to event and figure out what DOM to update is error prone. With React, you don't think about patching DOM to the right result, you only think about how the final result should looks.
Understanding to latest state of document overtime is also harder with manually patched DOM. You can't be sure how the current DOM looks like after lots of patching.
With React, you know exactly how the current document looks like, given value of props and state. Every programmer knows that referential transparent function is easier to reason about than state full function. React's render method makes rendering a referential transparent function, as opposed to manually patching part of the DOM.
React is not about performance, it's about making it easier to write Component that works. Virtual DOM helps making the idea of rendering the whole thing possible, which happens to also make it fast.
Updating a hundred on-screen elements requires special performance optimizations - are we back in 1985? Articles like this tend to confirm my prejudice that most new JavaScript frameworks are useless for real-world software.
I know that's not the full picture, but what I don't understand is why you would build something on these technologies when the practical performance ceiling of the framework magic is so achingly low, and once you hit it, you'll be spending much of your time fighting the framework that was supposed to be boosting your work.
The implementation feels like a complete overkill to me. The most obvious one being the Column component. I don't think you can judge the whole library on one instance where it's used (seemingly) without much experience and with an over the top approach.
That's not a performance optimization, you're supposed to implement "shouldComponentUpdate" on React components. Not sure what you mean by "spending time fighting the framework" either, it's one line of logic.
In case you missed the point of the article: it's not that you have to implement that method, but that you've to be careful implementing it because JS has mutable objects by default.
Also, when he's talking about "render" it's not a simple rasterization, it's actually manipulating the document tree and triggering a layout engine. Apples and oranges. If he wanted speed he could render his graphics on a canvas, then your 1985 comparison would make sense.
Let's educate ourselves about the subject before venting?
Hi! I'm the author and was very surprised to see my post here. I mainly wrote it as a reference for my future self.
Someone pointed out that I've muddied up the distinction between the DOM and react's virtual DOM. That is entirely possible! I should point out that I am a React novice and in no way an authoritative source.
I'm assuming when a render function gets run, it does an actual DOM render, but I could be wrong.
The render function only renders to the virtual DOM, which React diffs with the previous rendered virtual DOM to decide what changes to the real DOM have to be made. That's why the render function is, or should be, efficient.
Hi! That might be my comment down below. There's a nice article about how the diffing works here: http://calendar.perfplanet.com/2013/diff/ The important bit is that the diff is applied to the old and new virtual doms, and it is the render method that gets called to compute the new virtual dom. Only after the diff does the real dom get updated.
Hi! I'm the author and was very surprised to see my post here. I mainly wrote it as a reference for my future self.
Someone pointed out that I've muddied up the distinction between the DOM and react's virtual DOM. That is entirely possible! I should point out that I am a React novice and in no way an authoritative source.
I'm assuming when a render function gets run, it does an actual DOM render, but I could be wrong.
I recommend reading swannodette's The Future of JavaScript MVC Frameworks[1], which was the article which first got me to try React, after earlier passing it by. This meant I was coming to React via good examples of how to use it in an optimisable way, already thinking about reference equality of the props I was passing, and whether changes within state object structures were observable in my application (mutation vs copying etc).
Now that React has had a large recent influx of new users, hopefully these key concepts are not lost in the deluge of new blog posts and demo applications. Those who are championing React within groups and organisations should try to make sure developers who are more passively following are made aware of such useful ideas. Javascript (and software engineering in general) has a long history of collectively forgetting important ideas only to rediscover them later, but it would be better to be proactive than to leave it up to the archeologists.
I have been messing around with a reference cursor approach to rendering that does provide a bit of a performance improvement over the immutable + row component solution.
my results were:
Vanilla JS DOM updates (~180 fps)
React with stupid 10k Components being checked for ShouldComponentUpdate (~6 fps)
React with sane approach using Row component and immutable data (~75 fps)
React with my above described approach (~100 fps)
25 comments
[ 2.5 ms ] story [ 58.7 ms ] thread> React’s whole thing is that it doesn’t do unnecessary DOM manipulation, but clearly it is here. What gives?
This is not really true. Angular does dirty checking on the model backing the DOM, while libraries like Mithril or React do it on a virtual DOM that you have to recreate from scratch on every frame.
If you want to really avoid DOM hangups, just use a library like GreenSock or FastDOM.
Other than this, all these frameworks essentially do dirty checking when it comes time to render. Angular does it on the model, and React / Mithril do it on a virtual DOM, leaving it up to you how you update the virtual DOM. Usually they want you to recreate the entire DOM from the beginning, and then try to optimize the tree walk using immutability.
In any case, you don't need anything nearly as fancy as this. You can just subscribe to events when your model changes, and use FastDOM to update your DOM on those events. It is more efficient as it does only the minimum work necessary, instead of dirty-checking, albeit sometimes it may draw the same HTML in the same place.
It's in enabling developer to think only in "recreating the whole DOM".
Subscribing to event and figure out what DOM to update is error prone. With React, you don't think about patching DOM to the right result, you only think about how the final result should looks.
Understanding to latest state of document overtime is also harder with manually patched DOM. You can't be sure how the current DOM looks like after lots of patching. With React, you know exactly how the current document looks like, given value of props and state. Every programmer knows that referential transparent function is easier to reason about than state full function. React's render method makes rendering a referential transparent function, as opposed to manually patching part of the DOM.
React is not about performance, it's about making it easier to write Component that works. Virtual DOM helps making the idea of rendering the whole thing possible, which happens to also make it fast.
http://jsfiddle.net/zme8f7k8/1/
Edit: for comparison, a VanillaJS re-render: http://jsfiddle.net/zme8f7k8/2/
I know that's not the full picture, but what I don't understand is why you would build something on these technologies when the practical performance ceiling of the framework magic is so achingly low, and once you hit it, you'll be spending much of your time fighting the framework that was supposed to be boosting your work.
In case you missed the point of the article: it's not that you have to implement that method, but that you've to be careful implementing it because JS has mutable objects by default.
Also, when he's talking about "render" it's not a simple rasterization, it's actually manipulating the document tree and triggering a layout engine. Apples and oranges. If he wanted speed he could render his graphics on a canvas, then your 1985 comparison would make sense.
Let's educate ourselves about the subject before venting?
Someone pointed out that I've muddied up the distinction between the DOM and react's virtual DOM. That is entirely possible! I should point out that I am a React novice and in no way an authoritative source.
I'm assuming when a render function gets run, it does an actual DOM render, but I could be wrong.
Someone pointed out that I've muddied up the distinction between the DOM and react's virtual DOM. That is entirely possible! I should point out that I am a React novice and in no way an authoritative source.
I'm assuming when a render function gets run, it does an actual DOM render, but I could be wrong.
Now that React has had a large recent influx of new users, hopefully these key concepts are not lost in the deluge of new blog posts and demo applications. Those who are championing React within groups and organisations should try to make sure developers who are more passively following are made aware of such useful ideas. Javascript (and software engineering in general) has a long history of collectively forgetting important ideas only to rediscover them later, but it would be better to be proactive than to leave it up to the archeologists.
[1] http://swannodette.github.io/2013/12/17/the-future-of-javasc...
https://github.com/omniscientjs/omniscient/issues/93
my results were: Vanilla JS DOM updates (~180 fps) React with stupid 10k Components being checked for ShouldComponentUpdate (~6 fps) React with sane approach using Row component and immutable data (~75 fps) React with my above described approach (~100 fps)