Skip to content

Latest commit

 

History

History
102 lines (73 loc) · 4.87 KB

File metadata and controls

102 lines (73 loc) · 4.87 KB

Performance

The techniques that make React fast are not new. We've known for a long time that touching the DOM is expensive, you should batch write and read operations, event delegation is faster...

People still talk about them because in practice, they are very hard to implement in regular JavaScript code. What makes React stand out is that all those optimizations happen by default. This makes it hard to shoot yourself in the foot and make your app slow.

The performance cost model of React is also very simple to understand: every setState re-renders the whole sub-tree. If you want to squeeze out performance, call setState as low as possible and use shouldComponentUpdate to prevent re-rendering an large sub-tree.

Virtual DOM (difference algorithm), event delegation, batched DOM updates all contribute to make React fast out of the box. But if rendering many items, it can still lag! To counter that we can use Immutable.js or RxJS observable.

Example:

http://binarymuse.github.io/react-primer/build/index.html?6

How to determine if you have a performance bottleneck?


  1. Browser should render at 60fps which give you 16ms to work with.
  2. Forced synchronous layouts

Keys

Keys are defined in parent components, not in child components.

class StoogeList extends Component {
  render() {
    return (
      <ul>
        {this.props.stooges.map (stooge) => {
          return <Stooge key={stooge.id} />
        }}
      </ul>
    )
  }
}

class Stooge extends Component {
  render() {
    return <li>{ this.props.stooge.name }</li>
  }
}

StoogeList has to specify the keys of each of its children. The Stooge component doesn't need to worry about keys at all, because it's only rendering a single element.

Mobile Performance with Text Input

var shallowEqual = require('shallowEqual')

shouldComponentUpdate(nextProps, nextState) {
  return (
    !shallowEqual(this.props, nextProps) ||
    !shallowEqual(this.state, nextState)
  )
}

Or

import shallowCompare from 'react-addons-shallow-compare'

shouldComponentUpdate(nextProps, nextState) {
  return shallowCompare(this, nextProps, nextState)
}

shallowEqual compare the value of the key on first-level only. Deeply nested object cannot use this equality check. Better to Immutable.js for that.

Be mindful of these 2 things:

  1. Callback handlers that are bound in render() will always fail shallowEqual. Define your callback in the constructor instead.
  2. In addition to event handlers bound in render(), it is probably also worth mentioning that any component which takes jsx children will also always fail shallowEqual, since the children elements will be re-created for every render.

Videos