reactjsperformancememoizationpremature-optimization

Is there an example where using React.memo/PureComponent has worse performance than not using it?


I have seen many times in discussions and articles (many of which are from developers of React) mentioning that React.memo or PureComponent comes with performance overhead, and should be applied only after actually measuring the performance.

But, as seen in this answer, it is counter-intuitive to think that the overhead of shallow comparisons on props can outweigh the cost of deep VDOM comparisons, and it seems hard to refute without a concrete example that actually shows the case where React.memo or PureComponent is indeed slower.

However, I have yet to find such an example, after spending a whole evening searching for more on this topic.

Is it because such an example is not so simple to construct? Or is it so trivial that the performance hit can be observed in most cases (so there is no need to make up some example code just to show this effect)?


Solution

  • As per my understanding, if the prop that passed from parent to child is guaranteed to change in every re-render, React.memo might hinder the perfomance because of the additional comparison performed on every re-render.

    For eg:

    import React, { useState } from "react";
    
    export default function Form() {
      const [text, updateText] = useState("");
    
      const handleSubmit = (e) => {
        updateText(e.target.value);
      };
      return (
        <>
          <Input value={text} onChange={handleSubmit} />
        </>
      );
    }
    
    const Input = React.memo(function Input(props) {
      console.log("render");
    
      return (
        <>
          <input value={props.value} onChange={props.onChange} />
        </>
      );
    });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

    In this case, the Input component will re-rendered every time when the parent re-renders since handleSubmit is not memoized and the reference will change every time. Adding memo will hinder the perfomance because it will force the prop comparison before re-render and the props comparison always returns false, so in result memo just added an extra object comparison for every render.