1

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>);
   }

} 
5
  • In both cases, you don't need to make a new wrapper function to call renderItem(); you can pass a reference to the function directly. Commented Sep 10, 2016 at 13:08
  • Yes, I know, but this is the simple example. Sometimes I need to wrap it to a function to look clean, otherwise it looks quite messy. Commented Sep 10, 2016 at 13:10
  • What I meant was: {this.props.itemList(renderItem)} or {this.props.itemList(this.renderItem)} will be equivalent. The performance difference is completely trivial. Commented Sep 10, 2016 at 13:11
  • defining it inside render will create it each time you re-render Commented Sep 10, 2016 at 13:26
  • why not benchmark this with JSPerf or MeasureThat yourself? Commented Sep 10, 2016 at 13:34

2 Answers 2

1

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 };
}
Sign up to request clarification or add additional context in comments.

Comments

0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.