React SFC vs ES2015 classes vs ES2015 classes with shouldComponentUpdate

benchmark for React Component * ES2015 classes * ES2015 classes with shouldComponentUpdate * Stateless Components

by koba04

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.24/browser.js"></script>
<script src="https://fb.me/react-with-addons-15.0.1.js"></script>
<script src="https://fb.me/react-dom-15.0.1.js"></script>
<script src="https://facebook.github.io/react/js/jsfiddle-integration-babel.js"></script>

<div id="container">
    <!-- This element's contents will be replaced with your component. -->
</div>

JavaScript 1.7

const {Perf, TestUtils} = React.addons;

class NormalItem extends React.Component {
	render() {
  	const {item} = this.props;
  	return (
    	<div>
      	<span>{item.id}</span>
        <span>{item.name}</span>
      </div>
    );
  }
}

class NormalItemWithShouldComponentUpdate extends React.Component {
	shouldComponentUpdate(nextProps) {
  	return this.props.item !== nextProps.item;
  }
	render() {
  	const {item} = this.props;
  	return (
    	<div>
      	<span>{item.id}</span>
        <span>{item.name}</span>
      </div>
    );
  }
}

const StatelessItem = ({item}) => (
	<div>
  	<span>{item.id}</span>
    <span>{item.name}</span>
  </div>
);

class App extends React.Component {
	constructor(props) {
	  super(props);
    this.state = {
    	items: Array.from(new Array(50).keys()).map(n => ({
				id: n,
			  name: `item:${n}`
			}))
    };
    this.onClick = this.onClick.bind(this);
  }
  onClick() {
  	Perf.start();
  	this.setState({
    	items: this.state.items.concat(
      	{
        	id: this.state.items.length,
          name: `item:${this.state.items.length}`
        }
      )
    }, () => {
    	Perf.stop();
      Perf.printInclusive();
    });
  }
	render() {
  	const {Item} = this.props;
  	return (
    	<div>
      	<button onClick={this.onClick}>add</button>
	    	{this.state.items.map(item => <Item key={item.id} item={item} />)}
	    </div>
  	);
  }
}

[NormalItem, NormalItemWithShouldComponentUpdate, StatelessItem].forEach(Item => {
  ReactDOM.render(
    <App Item={Item} />,
    document.getElementById('container')
  );
  TestUtils.Simulate.click(document.querySelector('button'));
});