
Efficient Nested React Components - bpierre
https://medium.com/@joshuawcomeau/efficient-nested-react-components-dd9347e9b3f3
======
skrebbel
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.

------
burnout1540
I'm missing something.

    
    
      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.

------
mpweiher
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%).

~~~
iamstef
although it would be awesome if this enabled time travel...

------
mambodog
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.

[1] [http://swannodette.github.io/2013/12/17/the-future-of-
javasc...](http://swannodette.github.io/2013/12/17/the-future-of-javascript-
mvcs/)

------
pavlov
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.

~~~
hcarvalhoalves
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?

------
jwr
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.

------
SnowmanJoshu
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.

~~~
DougBTX
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/](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.

~~~
SnowmanJoshu
Ohhh. Alright, that makes much more sense. I was assuming the diffing
algorithm took place pre-render. Thanks =)

------
serve_yay
The whole point of how React renders is that component rendering does not
equal DOM manipulation.

~~~
mg74
The article is talking about optimizing VDOM generation, not DOM manipulation.

~~~
DougBTX
The article seems to muddle the two, e.g., after showing that the method to
render virtual DOM elements has been called for each cell it says:

> React’s whole thing is that it doesn’t do unnecessary DOM manipulation, but
> clearly it is here. What gives?

------
lootsauce
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.

[https://github.com/omniscientjs/omniscient/issues/93](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)

------
DougBTX
I've put together a toy version here, any ideas for making it faster? Render
time goes >100ms for me at around 45x45.

[http://jsfiddle.net/zme8f7k8/1/](http://jsfiddle.net/zme8f7k8/1/)

Edit: for comparison, a VanillaJS re-render:
[http://jsfiddle.net/zme8f7k8/2/](http://jsfiddle.net/zme8f7k8/2/)

------
jjfine
Yet another react article that doesn't apply to me. Clojurescript/Reagent
kicks butt.

------
zkhalique
_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.

~~~
coderzach
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.

~~~
zkhalique
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.

~~~
joesb
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.

