Over the past couple of years, anonymous functions have really taken off the React community. A few days ago, I was on twitter and saw the following exchange:

Kitze was kidding (I hope), but for a while this was a very real debate. Especially when render props were first taking off. Since then, Hooks have made anonymous (inline) functions even more popular.

There have been a lot of claims of "this might affect performance" which is often countered with "well that's a micro-optimization." Up until now I haven't seen any real numbers, so I decided to get them on my own.

At first, I did this just by running a simple node script with various numbers for NUM_EXECUTIONS.

function runAnonymous() { for (let i = 0; i < NUMEXECUTIONS; i++) { (() => { // noop })(); }
} function named() { // noop
} function runNamed() { for (let i = 0; i < NUMEXECUTIONS; i++) { named(); }
} const startNamed = new Date();
runNamed();
const endNamed = new Date();
const diffNamed = endNamed - startNamed;
console.log(Named took ${diffNamed} ms); const startAnonymous = new Date();
runAnonymous();
const endAnonymous = new Date();
const diffAnonymous = endAnonymous - startAnonymous;
console.log(Anonymous took ${diffAnonymous} ms); const factor = diffAnonymous / diffNamed;
console.log(Thats a factor of ${factor.toFixed(2)}x!);

This code is hopefully straightforward. First it runs a loop where it generates an anonymous function and executes it, second it creates a named function then loops over it and runs it the same number of times.

For anything less than 10,000 executions I couldn't profile a difference. Both the named and anonymous executions took 0 ms.

At 10,000 executions we start to get some results

Matthew at Matthews-iMac in ~/src/react-perf/src on master
$ node anonymous.js Named took 0 ms
Anonymous took 4 ms
Thats a factor of Infinityx! Matthew at Matthews-iMac in ~/src/react-perf/src on master
$ node anonymous.js Named took 0 ms
Anonymous took 4 ms
Thats a factor of Infinityx! Matthew at Matthews-iMac in ~/src/react-perf/src on master
$ node anonymous.js Named took 0 ms
Anonymous took 3 ms
Thats a factor of Infinityx!

Creating an anonymous function 10,000 times took about 3-4 ms to execute. I decided to crank it up a notch and see how many executions it took to see a real difference.

At a million executions I was able to see the named function actually take some time to run.

Matthew at Matthews-iMac in ~/src/react-perf/src on master
$ node anonymous.js Named took 1 ms
Anonymous took 3 ms
Thats a factor of 3.00x! Matthew at Matthews-iMac in ~/src/react-perf/src on master
$ node anonymous.js Named took 2 ms
Anonymous took 4 ms
Thats a factor of 2.00x! Matthew at Matthews-iMac in ~/src/react-perf/src on master
$ node anonymous.js Named took 2 ms
Anonymous took 3 ms
Thats a factor of 1.50x!

These results were pretty inconsistent ranging from 1.5x to 3.0x. Just for fun, I decided to crank it up to a billion.

Matthew at Matthews-iMac in ~/src/react-perf/src on master
$ node anonymous.js Named took 1240 ms
Anonymous took 4117 ms
Thats a factor of 3.32x! Matthew at Matthews-iMac in ~/src/react-perf/src on master
$ node anonymous.js Named took 1053 ms
Anonymous took 4153 ms
Thats a factor of 3.94x! Matthew at Matthews-iMac in ~/src/react-perf/src on master
$ node anonymous.js Named took 1054 ms
Anonymous took 3798 ms
Thats a factor of 3.60x!

Now we're getting some meaningful data. Creating an anonymous function and executing it takes roughly 3.5 times as long as calling a function that already exists.

This initial data tells me that anonymous functions don't make a meaningful difference to the performance of your application. In the above example we're averaging around 3 nanoseconds to allocate an anonymous function. For that to matter, we need to be operating at an unimaginably large scale.

Moving On To React

The above example is pretty contrived. In a vacuum we see that anonymous functions have a negligible impact on performance, but what about in a real React application?

I decided to throw together a simple React application to see if anonymous functions made any difference to rendering a simple component. That looks roughly like this

function AnonymousNumberList({count}) { let list = []; for (let i = 0; i < count; i++) { list.push(<Number getNumber={() => i} key={i} />); } return list;
} function NumberList({count}) { let list = []; for (let i = 0; i < count; i++) { list.push(<Number number={i} key={i} />); } return list;
} function Number({number, getNumber}) { return ( <h1 style={{color: number != null ? 'red' : 'blue'}}> {number != null ? number : getNumber()} </h1> );
}

In this example, we can render a large number of h1 tags and see if using an anonymous function makes any difference from just passing a raw prop. I opened up the React DevTools and profiled how long it took to render each set of elements.

Without Anonymous Functions






Number of Elements Time to Render
1005.1 ms
100041.7ms
10000201.8ms
25000518ms

With Anonymous Functions





Number of Elements Time to Render
1006.1 ms
100043 ms
10000210.9 ms
25000453 ms

This data is not at all scientific, but it was pretty representative of what I've found. Having a single anonymous function as a prop makes no meaningful difference to React performance.

I did have one serious takeaway though.