DEV Community

Cover image for Common React performance mistakes 💣
KaRthick
KaRthick

Posted on

Common React performance mistakes 💣

Performance optimisation is one of the challenges of a software developer.

It is a big burden when you start to optimise the application after months | years of development. No other go actually we need to somehow visit the code back to optimising the application performance wise.

But the burden can be minimized by following some performance optimization & best practices while writing the code.

At the same time optimization is a "two edged sword" .

Performance-related changes applied incorrectly can even harm performance.

Here I'll explain some things that I've seen and faced in react applications.

React.memo

If you're using react, you'll be aware of this particular HOC. It is mainly used to memoize the whole component.
memozied children

this is a memoized child component that receives handleOnClick as the props . So as per the memoization logic this component should re-render only if any of the props changes rit ?? that's how React.memo works but wait let's create a parent component and check.

Parent memo

perfect so during every onClick trigger in the child component parent state value changes but the props received in the child didn't change, so child component won't re-render since we memoized.

But wait here's where the real issue comes in if you try the above code in any editor or there's a codesandbox below you can see that the React.memo is broken!, child component will re-render for every state change even though the prop is same.

Is something wrong with the React.memo 🤯 ?

Nope ! every time when the parent component re-renders a new instance of the handleOnClick function is created. Hence is leads to break the memoization and re-renders the child component every time.

So, If you just wrap the child component with React.memo there's no assurance that I will just memoize and work.

But cool hook useCallback can come in to help you out ! . Wrap the handleClick function inside the useCallback hook and try the same code React.memo will just work as expected.

callback wrapper

but the above one is also overratted I would say , will explain this why later in the article
play here

Don't use the React.memo in a component that props is frequently changing, it will result to an extensive calculations.

Inline functions

return (
 <div>
  <button onClick={()=>setState(state+1)}>Increment</button>
 </div>
 )
Enter fullscreen mode Exit fullscreen mode

whenever a developer caught this code everyone (including myself 🤩) update the following code and will be like !

const handleIncrement = () => setState(state+1);
return (
 <div>
  <button onClick={handleIncrement}>Increment</button>
 </div>
 )
Enter fullscreen mode Exit fullscreen mode

yeah I've fixed a dam performance issue I going to get 100 performance score in lighthouse.

gif

but inline is acutally fine in this case !! if you have a concern try working with this

useEffect(()=>{
console.log('Executing')
},[setState])

you cannot use a user defined function inside the useEffect if you're using eslint it will warn you !! but the above code will just work fine because react is smart in this case it knows that setState will never change !.

Caution❌ : In-line functions shouldn't be called without arrow functions

<button onClick={handleIncrement()}>Increment</button>
Enter fullscreen mode Exit fullscreen mode

❌ this might result your code to an infinite loop

useCallback

Does it make sense using this hook here??🤔

this is the first question you should think off before use using these performance hooks like useCallback and useMemo .

The same example used above is also a overrated one , don't get confused here above example is just to explain you how things works ! but imagine the child component just re-renders a "div" and a "p" tag . There's no expensive calculations or any CPU affecting operations here, So why useCallback here ?

If the child component consist of large amount of data or a extensive calculations, the callback function that you're passing can be wrapped up using useCallback .

Remember Even useCallback() returning the same function object, still the inline function is re-created on every re-rendering useCallback() just skips it. So the re-render will be less commutated than using the useCallback here !

The same set of rules can be applied to useMemo too


Manage your Work From Home 🏡 issues using this [kit] a helper site I've made (https://dev.to/karthick3018/manage-work-from-home-effectively-using-wfh-kit-6bc)


check my dev projects on github
Follow me on twitter
connect with me on linkedIn
check my styles on codepen


Thanks for your time
Happy coding ! Keep Sharing
Stay Safe

Discussion (8)

Collapse
dikamilo profile image
dikamilo

Using react memo should not be the first thing to do and think about. The main problem here are re-renders caused by changing state that is "too global", "too high" in the component tree. So, splitting components to smaller components, move state management to component that actually use them and use React Context to share state/logic between components without causing re-render to large part of component tree. Also, React Developer Tools with Profiler help a lot of finding what's going on.

Collapse
aspiiire profile image
Aspiiire

Great article for an important topic, thanks for sharing 😁

Collapse
lukeshiru profile image
LUKESHIRU

About the inline functions, take a look at this article by Ryan Florence (co-creator of react-router). The TL;DR would be: In real life scenarios, it doesn't matter much, just write your code as you want to write it. If you prefer to have callbacks for events in external functions to make it more readable, do it. If you prefer a more inline approach, that's ok as well.

Collapse
karthick30 profile image
KaRthick Author

yeah true ! I personally I prefer callbacks but at the same time mentioned it to break that usage of in-line functions can be valid too

Collapse
valeriavg profile image
Valeria

Advices you provide have no affect on scaling, you might want to rethink the foreword.

Collapse
karthick30 profile image
KaRthick Author

thanks for the feedback ! suggest any better one or provide some scaling tip that might help people

Collapse
valeriavg profile image
Valeria

As you wish!

React allowed us to prototype applications much faster, but it rarely stays the same. Fixes, new features, redesign - these are all welcomed changes, but a growing pain nonetheless. Here are some tips & tricks to make it as easy as possible...

I'd like to explain why I even bothered to criticise, as offending you was never my intention.

Performance optimisation should always be measured first. Optimised code is much harder to read and maintain. Of course, when the app doesn't load at all due to an eternal loop it's a very easy measurement and decision to make.

What's for the scaling - it is a process of making your service available and usable for a bigger amount of clients at the same time (in most cases). When you talk about client code, aka front-end, it doesn't have any effect on how many users can use it at the same time, as each one of them runs their own copy.

Hope that helps!

Thread Thread
karthick30 profile image
KaRthick Author

no no not offending just asked for a better clarification! always there should be a debate for better result . Yeah word scaling is mis-leading here my intension is to mention both performance & scaling is a burden . But your thought is valid too , updated my article hope it's fine now