Keep Your React Redux Healthy, Performance Optimization Story

George Shevtsov
Frontend Weekly
Published in
4 min readMar 26, 2017

I just want you to know, I am here to be honest about React optimization.
If you are using React without Redux, I guess you should question your views on life now, because it is sooo pure and immutable, you’ll totally love it, I promise. It is like having an omnipotent indestructible swiss army knife except that you’ll have to build or get each and every other piece except for the blade somewhere on npm. React without Redux can surely be rated as a blade, but it is prone to mutation and side-effects, which makes it blunt.

Easy to write easy to mess up

Rumor has it, React apps are easy to write, although things which are easy to do, are very easy to spoil, like children, or choices in life or sandwiches.
But let’s get to the point, I am sure everyone passes props and creates containers, so please ask yourself this question.

Am I doing it right???

Consider this component and props passed to it. It is so bad.

Since it is all JavaScript, and React re-renders a component every time a component finds differences in previous and next props either it is an object or an array literal, it won’t be equal to the static self every update. So it is better to pass already defined static objects and arrays i.e.

Functions are a slightly different story. You shouldn’t pass a freshly created anonymous function down your component. Create it somewhere, it is totally fine. If you go with my hint of creating a function in a class component as a method, you will need to bind it somewhere.

So where do I bind functions then?

Constructor is a great place for that. Binding a function in a render method, will create a freshly bound function every render call, which is a totally new thing to JavaScript at the point of comparing props, although it may be the same thing to your understanding. Constructor method is called only once in a lifetime of a component right before componentWillMount. Have a look see.

You may have heard something about shouldComponentUpdate. To me this is a bomb of a sudden action. It’s been said that it may improve your performance, but things which may do something should be treated as things which may do absolute opposite of what was expected in the first place. I suggest looking at a PureComponent. It is a React entity like good old Component. It does a shallow comparison of props for you in its shouldComponentUpdate.

Shallow is not a savior.

React doc suggests using it for pure components with simple props, state and pure simple children. Although if data structures passed to a given component are immutable which is Redux way obviously, PureComponent won’t be harmful.

Above-stated points are just best practices. It is always up to you what you pass in. The most important fact is — it is mainly props which can kill your app’s performance, and event listeners, ok, and non-react DOM manipulations, but last two things are a total different story.

You can track your app’s performance with react-addons-perf. It records and outputs your components’ re-render count and wasted render time.

  • Wasted render time grows when you pass your object/function/array wrong.
  • Render count is messed up because you do updates to your reducers.

Isn’t it meant to work this way, the reducers I mean?

I’ll dig deeper to explain my point. We attract reducer’s data into our components through props by using mapStateToProps, it is a very smart function by the way, check Redux Doc.
So every update to a reducer data no matter what it is, since it is immutable, will go straight to the component and make it update, because this is what we want right, but together with that it will update all the children, if you do this.

{…this.props} — is passing all bunch of data to our components, it is probably handy and neat for guys who don’t like piling up props in their render methods declaration, but it is not healthy.

Now let’s think here.

I want to discuss the last piece of code. I’ll be using names of reducers and components further, please don’t be confused, alright.

If TotalsTable doesn’t need bills, and payments, although it still gets them together with totals through {…this.props}, it will still be updated if they change but if, at the same time, a vitally needed reducer totals won’t update, the component will do. How uncool is this?

It is tremendously necessary for performance to pass props like in the next example.

With the above scenario, our components will be updated only when the props they rely on are.

There is one other case.
Reselect.
It is a good library if you’re filtering or sorting or transforming your data in some way like this.

Filter and map are methods which return a newly created array, which in its turn will be a case for a component to update even if the data hasn’t changed. Reselect gives an ability to create a selector, it is a memoized function, which returns same piece of data if the input data hasn’t changed. It should save a couple of renders and wasted render milliseconds, I guess.

There are a ton of articles on the point of optimization react performance.
I consider fixing such imperceptible and easy things is the key to keep your app healthy.

Keep your app healthy, and you might not need writing your own shouldComponentUpdates.

It may be hard to believe but it is going to make a significant change in your apps performance. Although you may not visually see the difference, there may be a massive change in render count numbers and wasted render time.

Just check it.

Before optimizing track your current app’s performance state, with react-perf, make a screen shot of that, if you don’t have a photographic memory. And then, go ahead, optimize with what you’ve learnt, then track again and voilà.

--

--