Today we’re going to talk a little bit about memoization. And no, that’s not a spelling error. And even better, is sounds a lot more complicated than it really is.
3 min read
·
By Jan Gylta
·
December 9, 2018
So, what is memoization? First, we need to be able to identify deterministic or pure functions as they are sometime referred to in the react world. Basically, what that means is that the function will, given the same input always return the same output. A simple example of this would be a function called add. Given 2 and 3 as input, it will always return 5 as shown below.
// Deterministic / pure function
function Add(props) {
const sum = props.first + props.second;
return (
<span>
The sum of {props.first} and {props.second} is {sum}
</span>
);
}
// This will allways return the same
<Add first={3} second={4} />;
// Also, for reference, here is an example of a non-deterministic function
function Since(props) {
const msAgo = new Date() - props.postDate;
const secondsAgo = Math.round(msAgo / 1000);
return <span>From {secondsAgo} seconds ago.</span>;
}
// This may result in different output even though the input parameters stay the same
<Since postDate={new Date(2018, 11, 10)} />;
Now, since the function always returns the same value given the same input, what we can do is cache or store the result and the next time the function is called with the same input parameters, return the stored result instead of actually executing the function. That is memoization!
This doesn’t make much sense though if the function is just adding two numbers, but if the function has some time-consuming logic, this can result in huge performance gains.
There are some things you need to keep in mind when using memoization. If the same function is called with called with lots of different input parameters, you risk ending up using a lot of memory since every result is stored. A workaround for this could be either removing results from memory after a certain time period or, in many cases, just storing the last result, like Reacts pure component.
So how does this translate into the react world? If you use a react class component, you have the option of extending React.PureComponent
instead of React.Component
. If you do so, React will check the state and props and only re-render the component if they have changed, basically giving you a simplistic memoization function with limited history. If you use functional components however, react will call the function on every render.
As you now are an expert on memoization, you should be able to write your own memoization function or component for React. However, it is usually not a good idea to reinvent the wheel, so here are a few libraries, in no particular order, that can help you along.
memoize-one
This is a simple and very small library that, as mentioned earlier, only remembers the latest input parameters and result of a function. This means you don’t have to worry about memory issues etc.
react-memoize
This is a react library with a more advanced functionality that should cover most of your needs when using memoization in an React application.
Lodash
If all you need is a simple memoization function, keep in mind that lodash has one built in.
Moize
Moize is a very feature rich generic javascript library for memoization. It also has built in support for React.
Reacts next big thing seems to be hooks, coming early year. The alpha version is already out and it contains two hooks intended for memoization, useCallback and useMemo.
If your using Redux and find this interesting I would also recommend you take a look at the reselect library which basically enables you to easily create computed state which both helps you reduce the amount of state you need to store and at the same time leverages the advantages of memoization for excellent performance.