React renders unnecessary components

(Ben Carp) #1

In this simple Create-React-App application , I have a simple, static, Header component. For readability the header is held in a separate component. When using : Dveloper Tools - React - and selecting heighlight updates, I’m surprised to see that the Header component renders each time the destination changes. It was originally build as a functional component; Trying to change it to a React.pureComponent or React.Component with a ‘shouldComponentUpdate’ function that returns false did not change the result.
I guess this gets to the ‘Virtual Dom’ and does not render to the actual dom, but in more complicated apps it is still costly. Any suggestions?


(Mikayel) #2

try React.PureComponent

(Ben Carp) #3

Thanks. As I wrote, trying to change the component to a React.pureComponent … did not change the result.

(Mikayel) #4

Sorry, I was not carefuller. Virtual Dom re-rendering is happening always, and that is the React core philosophy. And it is not costly for real world apps. Dom manipulation is very slow and react is well optimized for that.

(Peter Bengtsson) #5

I find it really hard to believe the Header component re-renders when you make it a React.PureComponent.
Try this:

  • First, put a console.log('rendering Header', new Date()) right before the return inside that component.
  • Assure yourself that it logs every single time the App component renders. Expected.
  • Change it from a functional component to a class based React.PureCompnent. Keep the console.log line.
  • Check that the console.log ceases to happen even if the App's render is run.

(Ben Carp) #6

Thank you @peterbe!
You are correct. I added a console.log command to the render method, and it shows that the method doesn’t run when shouldComponentUpdate returns negative, or when we extend React.PureComponent. However Chrome’s React extension - heighlight updates - still heiglights the Header. I guess the reason for it is that the parent - the app component render function runs.

(Peter Bengtsson) #7

That’s actually very interesting observation. I personally never use/used the React dev tools in either Firefox or Chrome.

Also, sorry if this sounds patronizing but I strongly advice against shouldComponentUpdate. Either switch to PureComponent or think of a fresh way to rearrange your component so that it becomes easier to reason about without having to meddle in that life-cycle hook.

(Ben Carp) #8

Thanks Peter,

It doesn’t sound patronizing, but I think it requires further explanation. Why do u strongly advice against it? I didn’t work with other React developers much, but it seems shouldComponentUpdate is often used.

I understand that PureComponent, and if using Redux a connected component, make this life-cycle hook much less needed (and when combining it with the Immutable library completely unnecessary). Is this the reason for you advice?

(Peter Bengtsson) #9

This is a good start:

One reason I dislike shouldComponentUpdate is because it’s only a matter of time till there’s a new prop or state that gets added and now you need to rewrite your shouldComponentUpdate logic.
Also, the logic is often smelly. It’s cryptic with double negatives and it doesn’t read very naturally.

I don’t understand your point about “Redux connected component”. Perhaps there’s something new to Redux I didn’t know but it’s not in this business. Its job is to call the component so it doesn’t get itself involved in the render or not debate. Unlike Mobx which effectively replaces the shouldComponentUpdate with its own implementation.

(Baudin999) #10

I think it is a Virtual DOM thing. The Virtual DOM is almost always entirely rebuild. It’s where a part of the lag in
large React applications comes from. I believe the re-creation of the Virtual DOM is done by React-DOM and is done on the same thread as the “normal” UI thread.

That said, recreating the Virtual DOM is nothing compared to updating the actual DOM and reflowing your web page so the cost of re-calculating the Virtual DOM is a really small price to pay for the limited number of updates which need to be done to the DOM.

I personally wouldn’t be put off by something happening in the React dev tools. I always look at the actual DOM representation in Chrome and watch which nodes “flicker”. Those things are the real performance pain.