Reputation: 333
Is there any performance difference between defining a function inside render
function or defining it in the class scope?
render
function scope:
render() {
const renderItem = (item) => (<li>{item.name}</li>);
return (<ul>
{this.props.itemList.map((item) => renderItem(item))}
</ul>);
}
class
scope:
export default class MyComponent extends React.Component {
const renderItem = (item) => (<li>{item.name}</li>);
render() {
return (<ul>
{this.props.itemList.map((item) => this.renderItem(item))}
</ul>);
}
}
Upvotes: 1
Views: 168
Reputation: 1536
Yes, somehow there's a difference of performance.
But this difference is so so so so minimal, that you can even notice or tell what is the difference.
The thing is, when you define the renderItem
inside the render
method, each time that the render
method is called, the renderItem
function will be recreated. In the other way, renderItem
is defined only once in a life.
Because of that you can think that the "outside" method will be faster. But the thing is, in the "inside" method, the renderItem
will be created only once per call. So if you have, for example, 1 million items to render, the "bottleneck" of the whole proccess will be the map
itself, and not the creation of the renderItem
method, gotcha?
But for test, I build this sample, to test both methods, insideFunction
and outsideFunction
. You can copy and run in your browser.
To test, you can run bench(10000)
to see how much time both methods would take with an array with 10000 elements (in my computer, the average time for this size is around 0.05~0.07 seconds.
You can also run several bench
tests and see the output average, with: nBenchs(10, 10000)
, run 10 bench(10000)
tests.
Conclusion: In my computer, running tests with array with 1 million positions, I got something around 7 seconds average, for both methods. Running this several times, in most cases, the "outside" method as half second faster that "inside". But keep this in mind, if you have a code that takes 7 seconds to return the output to the user, you should start thinking in other alternatives to decrease this value (like showing parts of the result first and faster). If you're building an aplication that handle with that amout of data and have heavy proccess algorithms (which is not common in web/react applications), then every action that save you 7% of the time (half second of seven, in this case) are precious.
(function() {
function renderItem(text) {
let item = document.createElement('li');
item.innerHTML = text;
return item;
}
function outsideFunction(array) {
return array.map(renderItem);
}
// exponse outsideFunction
window.outsideFunction = outsideFunction;
})();
(function() {
function insideFunction(array) {
function renderItem(text) {
let item = document.createElement('li');
item.innerHTML = text;
return item;
}
return array.map(renderItem);
}
// exponse insideFunction
window.insideFunction = insideFunction;
})();
// just build an array with n elements
function buildArray(n) {
let testArray = [];
for(let i=0; i<n; i++) {
testArray.push(`Text with index ${i}`);
}
return testArray;
}
// run nb test benchs with an array with n elements
function nBenchs(nb, n) {
let Ocount = 0, Icount = 0;
let result;
for(let i=0; i<nb; i++) {
result = bench(n);
Ocount += result.Oend;
Icount += result.Iend;
}
// output the average
console.log(`outsideFunction average: ${Ocount/(nb*1000)} seconds`);
console.log(`insideFunction average: ${Icount/(nb*1000)} seconds`);
}
// run a test bench with an array with n elements
function bench(n) {
n = n || 100;
let testArray = buildArray(n);
let start, Oend, Iend;
start = new Date();
outsideFunction(testArray);
Oend = ((new Date())-start);
console.log(`outsideFunction: ${Oend/1000} secods`);
start = new Date();
insideFunction(testArray);
Iend = ((new Date())-start);
console.log(`insideFunction: ${Iend/1000} secods`);
return { Oend, Iend };
}
Upvotes: 1
Reputation: 28747
Defining it in the class-scope will be marginally faster, because the function will only be created once. If you define it in the render-method, the function will be created every time the render-method is called.
That said, it's very unlikely it will have any noticeable impact.
Upvotes: 0