Search code examples
javascriptperformancereactjsecmascript-6stateless

React Stateless components - performance and PureRender


Everyone says that it uses stateless components will improve application performance. I noticed, however, that the use of stateless component in the wrong place can really reduce application performance.

This happens because the stateless components, render always, even if the properties have not changed.

In the case of stateful components we can use PureComponent, PureRenderMixin or implement own shouldComponentUpdate - thanks it noticed a big Increase in application performance when compared to stateless components.

I wanted to ask if there is some way to implementation something like pureRender for stateless component?. I'm not interested in wrapping stateless component in stateful components.

If this is not possible, so how is it really with performance in stateless components?

I prepared two simple examples, showing that what I wrote. Try change active button:

stateful PureComponent:

class List extends React.Component{
  constructor(props) {
    super(props);
    this.generateElements = this.generateElements.bind(this);
    this.changeActive = this.changeActive.bind(this);
    this.state = {
    	active: 0
    }
  }
	generateElements(){
  	let elements = [];
    for(let i = 0; i<=1000; i++){
    	elements.push(<Element key={i} 
      											 index={i}
                             active={this.state.active === i} 
                             changeActive={this.changeActive} /> )
    }
    return elements;
  }
  changeActive(index){
  	this.setState({
    	active: index
    });
  }
  render() {
    return (
    	<div>
        <div className="classButtons">
          {this.generateElements()}
        </div>
      </div>
    )
  }
}

class Element extends React.PureComponent{
  render() {
  console.log('render');
    return(
      <button onClick={this.props.changeActive.bind(null, this.props.index)}
      		    className={this.props.active ? 'active' : null} >
      	Element {this.props.index}
      </button>
    )

  }
}

ReactDOM.render(<List />, document.getElementById('container'));
button{
  display: block;
  margin-bottom: 2px;
}
button.active{
  background-color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.3.1/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.3.1/react-dom.js"></script>

<div id="container"></div>

Stateless component:

class List extends React.Component{
  constructor(props) {
    super(props);
    this.generateElements = this.generateElements.bind(this);
    this.changeActive = this.changeActive.bind(this);
    this.state = {
    	active: 0
    }
  }
	generateElements(){
  	let elements = [];
    for(let i = 0; i<=1000; i++){
    	elements.push(<Element key={i} 
      											 index={i}
                             active={this.state.active === i} 
                             changeActive={this.changeActive} /> )
    }
    return elements;
  }
  changeActive(index){
  	this.setState({
    	active: index
    });
  }
  render() {
    return (
    	<div>
        <div className="classButtons">
          {this.generateElements()}
        </div>
      </div>
    )
  }
}

const Element = ({changeActive, index, active}) => {
	console.log('render');
  return(
    <button onClick={changeActive.bind(null, index)}
            className={active ? 'active' : null} >
            Element {index}
    </button>
  )
}

ReactDOM.render(<List />, document.getElementById('container'));
button{
  display: block;
  margin-bottom: 2px;
}
button.active{
  background-color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.3.1/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.3.1/react-dom.js"></script>

<div id="container"></div>


Solution

  • I noticed, however, that the use of stateless component in the wrong place can really reduce application performance.

    Indeed. For complex components, you should avoid stateless components.

    Everyone says that it uses stateless components will improve application performance

    you miss one important part... in Future.

    I wanted to ask if there is some way to implementation something like pureRender for stateless component?

    No, not yet.

    If this is not possible, so how is it really with performance in stateless components?

    Components that implement shouldComponentUpdate will perform better.


    See here my statements backed up by the React team. Two important quotes from there

    For complex components, defining shouldComponentUpdate (eg. pure render) will generally exceed the performance benefits of stateless components.

    Dan Abramov:

    There are currently no special optimizations done for functions, although we might add such optimizations in the future. But for now, they perform exactly as classes.