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)?
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.