Optimization is the top concern of every developer when building any software, especially a web application.
Here, I will introduce some tips to help you optimize application performance for React that I have learned.
Tip 1: useMemo, useCallback
A function is created inside a component, when that component renders, the internal components of the component including the function are rendered.
In case the function has not been used but is rendered with the component, the rendering of the function is unnecessary.
Besides that, if repeated many times, will lead to a decline in the performance of the application.
To solve problems with the performance of the app that occur. React provides us with 2 hooks: useMemo and useCallback.
useMemo
useMemo is the same as the concept of React memo, but there are clear differences.
If React memo was born with the goal of avoiding repeated rerenders then useMemo avoids recalculating a function repeatedly each time the component re-renders.
The essence of useMemo is to re-ching the return value of the function.
Each time the component rerenders it checks the parameter value passed to the function, if that value has not changed then the return value has caching in memory.
Conversely, if the parameter value passed changes, it will perform a recalculation to return the value, then caching the value again for subsequent rerenders.
useMemo takes in 2 parameters: 1 is the function that returns a function call (plusFive), and 2 is a dependent array. Only when the dependent array changes, can the function be called.
useMemo will return the result of making the function call and save it to memory to prevent the function from calling back when using the same dependent array (or unchanged dependent array).
const memoizedMemo = useMemo(() => { doSomething(a); }, [a]); |
useCallback
useCallback has the same task as useMemo, but differs in that the function passed to useMemo is required to be in the rendering process while for useCallback it is the callback function of a certain event such as onClick.
const memoizedCallback = useCallback(() => { doSomething(b); }, [b]); |
Example to use useMemo and useCallback:
import { useState, useCallback, useMemo } from "react"; import ReactDOM from "react-dom"; function myComponent () { const [numberState, setNumberState] = useState(1); const calculate = useCallback(num=> { return num*5; }, []); const memoizedNumber = useMemo(() => { return calculate(numberState); }, [numberState, calculate]); const handleClick = useCallback(() => { setNumberState(memoizedNumber); }, [memoizedNumber]); return( <> <div>Number State: {numberState}</div> <button onClick={handleClick}>Click</button> </> ); } const rootElement = document.getElementById("root"); ReactDOM.render(<myComponent />, rootElement); |
Tip 2: React.PureComponent/React.memo
PureComponent is exactly the same as Component, except that it handles shouldComponentUpdate for you.
A simple React.Component that has the shouldComponentUpdate brother always returns true.
However, it can lead to a few unnecessary renderings. One of the most practical ways is to re-optimize shouldComponentUpdate so that it checks if it needs rendering.
When props or state changes, PureComponent makes a shallow comparison on both props and state.
The component, on the other hand, will not compare the props and state of the present with the future.
As such, the component will be re-rendered by default whenever shouldComponentUpdate is called.
React.memo
const myComponent = React.memo((props) => { |
React.PureComponent
import { PureComponent } from "react"; export default class myComponent extends PureComponent { |
Conclusion:
By following these tips, you will be able to improve performance with useMemo, useCallback, and React.PureComponent/React.memo.
Here are some of the significant ways to improve performance that I learned. If you have any other way, please leave a comment and share it with me.
References: https://legacy.reactjs.org/docs/getting-started.html