Alex Sidorenko

Optimizing React performance without refs and memo

January 04, 2023

Frequent state updates in React can lead to performance problems. For example, this component shows the current mouse position while rendering an expensive JSX.

How can we make it faster? Should we find a way to stop re-rendering the component that often? Is it a case for refs? Should we apply memoization with memo or useMemo? There is another solution

But first, why exactly is it slow?

React is smart enough to update only the minimum necessary parts of the DOM. If we check the DOM inspector, we’ll see that the only things that get updated are the mouse coordinates.

And yet, the app is still slow. That’s because every render returns a tree of elements that React has to compare with a tree from the previous render to determine whether to change the DOM (Reconciliation). And we generate a lot of elements in the component that is being re-rendered on every mouse move.

Highlighting the part of the code that generates 30000 elements

State colocation

The simplest way to avoid this type of performance problems in React is to colocate the state with the parts of UI this state is updating.

In our case, the parts of our component related to the mousemove updates are 👇

Highlights parts of the code related to mousemove updates

Let’s extract these parts into a separate component.

Now, let’s add children prop to our newly created component and pass the rest of JSX there.

That’s it 🎊. We isolated mousemove state updates within the component responsible only for those updates. Now our app is faster since it doesn’t need to re-render the expensive part of JSX on every mouse move. And all we did was move components around. No refs, no memoization.

Coding Challenge 🙌

The app in this CodeSandbox shows a current scroll position by re-rendering the entire component on the scroll event, and it’s not very performant. Could you make it faster without using refs and memo?

Hint: you may not need a children prop for this one

Send the link to your solution as the reply to this tweet.