Performance optimization in React | useCallback & useMemo hooks

Bibek Magar
wesionaryTEAM
Published in
5 min readFeb 9, 2020

--

Performance is very common thing that every developer may faces at some point after building the application. We architect, code and build the system which run perfect in our system but when it goes for production or after we deploy the system it actually feels slower than that of development.

So why is development app feels faster than of production?

During development, all our files are hosted in our local machine or our own computer which is specifically in port 3000(in React). It is very efficient and fast for us to download all of our bundles and files because we were just developing locally and speed is really quick where the speed of the internet connection doesn’t really concerns. But in production internet comes the big issue especially if we are building application for the country that have really slow internet connection.

Do not fall for tips and tricks!

“Performance optimization always come with a cost but do not always come with benefit”

So, do not optimize your code ahead of time or before it really needs, don’t write performance code and don’t fall for all the performance tips and tricks that we read all over the internet without proper reason to do so. We only optimize a code once there is a production or we really feels some line of code is making slow unless it is mandatory. We shouldn’t be eagerly optimizing our code and implement what we read without necessary.

Why ?? Not to implement tricks

Your code might not be slow to begin the optimization. We will optimize the code by measuring it in the first place. If we don’t measure and start optimization stop doing it. Only perform optimization when you notice application starts slow down and you notice there is the problem. Before looking for the potential solution find out why it is slowing down.

Don’t over optimize the application because when we optimize the code actually it makes slower. Optimizing the code means adding the lines of code where every lines of code come with a cost.

useCallback | Hook

useCallback help to memoize the function that we wrap in.

In REACT when parent component re-render inside parent, a child component also re-render. At each re-render child component will re-execute its functions. Using call back function, the re-execute of function will solve the issue.

Example 1.1:

import React, { useState} from "react";const collections = new Set();const App = () => {
const [num, setNum] = useState(0);
const displayLog = () => console.log("I am re-rendering");
console.log(collections);

const add10 = () => {
setNum(num + 10);
};
collections.add(displayLog); return (
<React.Fragment>
{num}<br />
<button onClick={add10}>Add value by 10</button>
<button onClick={displayLog}>Show Name</button>
</React.Fragment>
);
};
export default App;
Output of Example 1.1
console log of Example 1.1 after clicking “Add value by 10” 5 times

As we can see in the above console the more we click the button, the component get re-renders and functions get called which is unnecessary and costly for us. So, to prevent this unnecessary calling of function, we memoize it.

Example 1.2 (After implementing callback)

import React, { useState, useCallback } from "react";const collections = new Set();
const App = () => {

const [num, setNum] = useState(0);
const displayLog = useCallback(() => console.log("I am rendering" ), []); const add10 = () => {
setNum(num + 10);
};
collections.add(displayLog);
console.log(collections);
return (
<React.Fragment>
{num}
<button onClick={add10}>Add value by 10</button>
<button onClick={displayLog}>Show Name</button>
</React.Fragment>
);
};
export default App;
Output of Example 1.2
console log after implementing callback and clicking button 5 times

As we can see in the console there is no more unnecessary re-render due to the help of useCallback hook.

useMemo | Hook

useMemo returns a memoized value.

It is suitable for processing lot of data i.e. complex mathematical calculation or any complex task that takes times to calculate. First, it will do work at the first render and then on every re-render it display the cached version rather calculating the complex calculation again and again.

Example 2.1:

import React, { useState } from "react";
const App = () => {
const [num, setNum] = useState(0);
const add10 = () => {
setNum(num + 10);
};
const complexFunctions = () => {
console.log("I am doing complex task zZZZZZ");
return (num + 2 * 2 * 99999 * 999999 * 999999 * 99999) / 0.213123123123123;
};
const randomClick = () => {
console.log("Random button is clicked");
setNum(num - 10);
};
return (
<>
{num}
<button onClick={add10}>Add value by 10</button>
<button onClick={randomClick}>Random button</button>
<br />
Complex Value: {complexFunctions()}
</>
);
};
export default App;
Outpout of Example 2.1
console log of Example 2.1 after clicking random button 5 times

As we can see the unnecessary complex calculation is performing again and again which is costly if that function takes more than a seconds. So, to eliminate these unnecessary calculation we memoized the value by the help of useMemo.

Example 2.2:

import React, { useState, useMemo } from "react";const collections = new Set();
const App = () => {

const [num, setNum] = useState(0);
const [num2, setNum2] = useState(0);
const add10 = () => {
setNum(num + 10);
};
const complexFunctions = useMemo(() => {
console.log("I am doing complex task zZZZZZ");
return (num + 2 * 2 * 99999 * 999999 * 999999 * 99999) / 0.213123123123123;
}, [num]);
const randomClick = () => {
console.log("Random button is clicked");
setNum(num2 * 10);
};
return (
<>
{num}
<button onClick={add10}>Add value by 10</button>
<button onClick={randomClick}>Random button</button>
<br />
Complex Value: {complexFunctions}
</>
);
};
export default App;
Output of Example 2.2
console log of Example 2.2 after clicking Random button 5 times

As we can see… complexFunctions() is not being called because of useMemo hooks which is very efficient for complex calculations.

Thank you for reading :)

Follow me: beevekmgrz

--

--