Explore Blogs

Optimizing react performance: Understanding React.memo and useMemo

bpi-react-memo-vs-use-memo

Optimizing performance is essential for a smooth user experience. Two key techniques for this are React.memo and useMemo. While both enhance performance, they work differently and are used in various contexts.

In the world of React development, performance optimization is a critical aspect that can significantly enhance the user experience. Two powerful techniques in the React arsenal for achieving this are React.memo and useMemo. While both serve to optimize performance, they do so in different ways and are used in different contexts. Let's dive into what each of these techniques does, how they work, and when to use them.

What is React.memo?

React.memo is a higher-order component (HOC) that helps optimize the rendering of functional components. Its primary function is to memoize the rendered output of a component, which means it stores the output and reuses it if the props haven't changed. This prevents unnecessary re-renders and can greatly improve performance, especially in complex applications.

How React.memo works

When you wrap a functional component with React.memo, React performs a shallow comparison of the component's props. If the props are the same as the previous render, React skips re-rendering the component and reuses the last rendered output.

Syntax

Here's a simple example of how to use React.memo:

const MyComponent = ({ data }) => {
  console.log('MyComponent rendered');
  return <div>{data}</div>;
};

const MemoizedComponent = React.memo(MyComponent);

In this example, MemoizedComponent is the optimized version of MyComponent. It will only re-render if the data prop changes.

Custom comparison

Sometimes, the default shallow comparison might not be sufficient. In such cases, you can provide a custom comparison function as the second argument to React.memo:

const MemoizedComponent = React.memo(MyComponent, (prevProps, nextProps) => {
  return prevProps.someProp === nextProps.someProp;
});

This custom function allows you to have more control over when the component should re-render.

How it works

The custom comparison function should return a boolean value:

  • true: If the function returns true, it indicates that the previous props (prevProps) and the next props (nextProps) are considered equal. In this case, React will skip re-rendering the component and reuse the last rendered output.
  • false: If the function returns false, it indicates that the props have changed, and React will proceed to re-render the component.

Let's consider an example to illustrate this:

const MyComponent = ({ data, anotherProp }) => {
  console.log('MyComponent rendered');
  return <div>{data}</div>;
};

const MemoizedComponent = React.memo(MyComponent, (prevProps, nextProps) => {
  return prevProps.data === nextProps.data;
});

const ParentComponent = () => {
  const [data, setData] = useState('initial data');
  const [anotherProp, setAnotherProp] = useState('some value');

  return (
    <MemoizedComponent
      data={data}
      anotherProp={anotherProp}
    />
  );
};

In this example:

  • The custom comparison function checks if prevProps.data is equal to nextProps.data.
  • If data has not changed, the function returns true, and MemoizedComponent will not re-render.
  • If data has changed, the function returns false, and MemoizedComponent will re-render.

What happens when it returns true?

When the custom comparison function returns true:

  • Rendering skipped: React skips the rendering process for the component. This means the component's render method is not called, and no new output is generated.
  • Performance optimization: By skipping the render, React avoids unnecessary computations and DOM updates, which can improve the performance of your application.
  • Reuse of previous output: The component reuses the output from the previous render. This is particularly useful for components that are expensive to render or have complex rendering logic.

What happens when it returns false?

When the custom comparison function returns false:

  • Rendering triggered: React proceeds to call the component's render method, generating new output.
  • DOM updates: The new output is compared with the previous output, and any necessary DOM updates are applied.
  • Potential performance impact: If the component is expensive to render, this can have a performance impact. Therefore, it's important to use React.memo judiciously and ensure that the custom comparison function is efficient.

The custom comparison function in React.memo gives you fine-grained control over when a component should re-render. By returning true when the props are considered equal, you can optimize performance by skipping unnecessary renders. Conversely, returning false triggers a re-render, ensuring that the component stays up-to-date with the latest props. Understanding how to use this feature effectively can help you build more efficient and performant React applications.

What is useMemo?

useMemo is a hook that memoizes the result of a function. It ensures that the function is only re-executed when its dependencies change. This is particularly useful for optimizing expensive calculations or stabilizing references to objects or functions.

How useMemo works

useMemo takes a function and an array of dependencies. The function is only re-executed when one of the dependencies changes. The memoized value is returned and remains the same as long as the dependencies do not change.

Syntax

Here's an example of how to use useMemo:

const MyComponent = ({ data }) => {
  const memoizedValue = useMemo(() => expensiveComputation(data), [data]);
  console.log('MyComponent rendered');
  return <div>{memoizedValue}</div>;
};

In this example, memoizedValue is the result of expensiveComputation(data). This computation is only re-executed when data changes.

Use cases

useMemo is commonly used to:

  • Optimize performance: Avoid expensive calculations on every render.
  • Stabilize references: Ensure that the reference to a value or function remains the same between renders, which can be important when passing props to child components.

Key differences

While both React.memo and useMemo serve to optimize performance, they do so in different ways:

Scope:

  • React.memo memoizes the rendered output of a component.
  • useMemo memoizes the result of a function within a component.

Usage Context:

  • React.memo is applied to a component as a whole.
  • useMemo is used within a component to optimize specific calculations or references.

Dependencies:

  • React.memo relies on prop comparisons to determine if a component should re-render.
  • useMemo relies on an explicit array of dependencies to determine if the memoized value should be recomputed.

Customization:

  • React.memo allows for a custom comparison function.
  • useMemo does not support custom comparison functions; it strictly relies on the dependencies array.

Example comparison

Using React.memo

const MyComponent = ({ data }) => {
  console.log('MyComponent rendered');
  return <div>{data}</div>;
};

const MemoizedComponent = React.memo(MyComponent);

const ParentComponent = () => {
  const [data, setData] = useState('initial data');

  return <MemoizedComponent data={data} />;
};

In this example, MemoizedComponent will only re-render if data changes.

Using useMemo

const MyComponent = ({ data }) => {
  const memoizedValue = useMemo(() => expensiveComputation(data), [data]);
  console.log('MyComponent rendered');
  return <div>{memoizedValue}</div>;
};

const ParentComponent = () => {
  const [data, setData] = useState('initial data');

  return <MyComponent data={data} />;
};

In this example, expensiveComputation(data) is only re-executed when data changes.

Conclusion

Both React.memo and useMemo are powerful techniques for optimizing performance in React applications. React.memo is used to memoize the rendered output of a component based on prop comparisons, while useMemo is used to memoize the result of a function within a component based on dependencies. Understanding when and how to use each of these techniques can help you build more efficient and performant React applications.

As we've seen, React.memo and useMemo are essential tools for any React developer looking to optimize their applications. By memoizing component outputs and function results, these techniques can significantly reduce the number of renders and computations, leading to a smoother and more responsive user experience. Whether you're dealing with complex UI components or expensive calculations, understanding how to effectively use React.memo and useMemo can make a world of difference in your application's performance.

Stay Updated

This site is protected by reCAPTCHA and the GooglePrivacy Policy andTerms of Service apply.