React Virtual Dom and Memo on Performance

Kasun Vimukthi
Nerd For Tech
Published in
5 min readMay 23, 2021

--

In this article, I will describe the concepts that react uses for gaining performance in rendering. I will explain the Virtual Dom concepts, Memo, useMemo hook in detail including,

  • What they are?
  • How they are gaining performance?
  • When to use them?
  • When should it be avoided?

In the first place, I have had an idea that they are isolated concepts/hooks that React uses for gaining performance. But, I was wrong. These are interconnected in a way in which your application is dedicated to the performance hit. Let’s work through each one in detail.

Virtual Dom (VDOM)

When a web page is loaded, the browser creates a Document Object Model of the page. Simply it is constructed as a tree of objects. Then what is VDOM? Well, it is a kind of abstraction layer that lies on top of the DOM in react applications. What React does is directly interact with the VDOM. Not with the actual dom. Then the ReactDom library will interact with the actual DOM and apply the updated elements only in the DOM manipulation.

ReactDom identifies the updated elements in VDOM by comparing the newly rendered VDOM vs the previous VDOM. This process is called diffing. If there are any changes then the changing element will be updated in the dom. That process is called reconciliation. If they are equal then there is no actual DOM manipulation at all. This will leads to performance gain because you are saving the number of times and number of elements that you are going to update the actual DOM since actual DOM updates are slow compared with processing diffing as they cause an actual re-draw of the UI elements.

This optimization is already done for you from React. But it is worth understanding them to identify how things working under the hood.

Let’s look at the following example. It is a simple react application that will display a “Hello, world” and typed name in the next line. The “Hello” component is not going to change whatever you type in in the input. but the “Name” component should change to the value that we typed in the input box. Since both Hello and Name components are wrap in the App component when the name state changes, the App component automatically re-render every child. Hence the unnecessary re-render will be called for every time a user inputs something. That can be observed with the console logs.

It is true that reconciliation process solving the problem even if your application performs unnecessary re-renders. However, think that a big component with a large number of children tries to re-render unnecessarily. Then, there are aspects that we should consider which might affect the performance as reasons of following.

  • re-render execute the render function and function components again
  • The diffing process will execute for a large set of elements

To overcome this performance issue, react introduce Memo.

Memo

Memo stands for memorization. In React what it does is when component rendering happens then it will be cached. When that component attempts to re-render with the same props then the cached value will be return instead of function execution. This contributes to a significant performance gain for components a having a large number of children and those children have nothing to do with the re-render. We just have to wrap our component in “React.memo” as follow.

Using React memo for Hello component

Let’s say we want to pass the display message to the Hello component from App component. I will create a msg object and pass it as a prop. Then you suddenly realize that memo is not working. That is because the memo does a shallow comparison. Since every re-render changing the reference of an object memo think that this is a new object. Therefore react will render the Hello component every time the parent component renders.

memo is not working

To overcome that issue we can pass a custom areEqual function as an argument to the memo. Then if the condition is satisfied it should return true for not re-rendering. Returning false will re-render the component.

custom areEqual function

As an alternative to this custom “areEqual” function React introduce useMemo Hook. It also returns the memorized value when the provided dependency changes.

useMemo usage

The memo is not implemented as default by React because of the following reasons.

  • For small components, it isn’t really beneficial. Instead it additionally execute some comparison function as well.
  • Memory consumptions

So there is an opportunity cost of using ReactMemo. It is not a good solution to use memo everywhere. Hence it is better to understand when to use a memo. Following are few conditions where memo can be useful

  • If a component renders the same content for similar props
  • If a content renders at high frequency (ex: stock data updates)
  • If a component is considerably heavy

--

--