We’re excited to release a tiny new open source project: react-fast-compare. react-fast-compare provides fast deep equality comparison, with specific handling for React. It’s a fork of Evgeny Poberezkin’s very clever (and very fast!) fast-deep-equal.
const isEqual = require("react-fast-compare"); isEqual({foo: 'bar'}, {foo: 'bar'}); // true isEqual(42, 42); // true isEqual(<h1>casserole or pizza</h1>, <h1>casserole or pizza</h1>); // true
Highlights
As the name implies, react-fast-compare aims to be the fastest deep equality comparison available. It’s very lightweight: under 600 bytes gzipped and minified. It does deep equality comparison by value for any object, as long as it doesn’t contain circular references. It also allows deep comparison of React elements.
Using with React
While projects like fast-deep-equal are amazing for general usage, they don’t handle circular references at all, which is one of the reasons they can be so fast. Unfortunately, this strategy doesn’t work for React elements, as they contain multiple circular references. For example, an element that contains a reference to its “owner” (or parent), which in turn contains a reference to its children, including the original element. react-fast-compare adds handling for these React-specific cases.
A component’s shouldComponentUpdate lifecycle method is a perfect use case for react-fast-compare, potentially saving you from needless re-renders.
import isEqual from "react-fast-compare"; class ExpensiveRenderer extends React.Component { shouldComponentUpdate(nextProps) { return !isEqual(this.props, nextProps); } render() { // ... } }
You should only use shouldComponentUpdate if you have “deep” props, which are any props that cannot be compared with a simple equality. Examples of deep props are objects, arrays, and dates.
If you don’t have any deep props (they are all shallow: strings, booleans, and numbers), you can just use a PureComponent. You could also consider using immutable data to allow for fast comparison of deep props, but it won’t work for every project.
Case Study: Victory
react-fast-compare was born from our work with Victory. We identified our equality check for shouldComponentUpdate as a performance bottleneck, which made sense, as it was saving us from a larger bottleneck: wasted re-renders. Our previous equality check was based on Lodash’s isEqual, and performed roughly as fast.
We ultimately realized that we needed handling for React elements, and decided to create and release react-fast-compare as a new project.
General Usage
react-fast-compare aims to be a very fast general deep equality check. Our goal is to remain as performant as fast-deep-equal.
You may be asking, ”what about Lodash?” Lodash is a powerful utility library, and its isEqual function is very thorough. react-fast-compare is faster by virtue of the fact that it’s doing less work. For example, react-fast-compare doesn’t track circular references or allow custom comparison functions like Lodash does.
What’s Next?
We would love feedback from the community, so give the library a try in your project. We were excited to see that Formik already incorporated react-fast-compare. Let us know what works well, and what needs work! You can file issues on github, or get in touch with me on twitter.