Dive into React Performance

672ba495b3eadfdb0daee60ed354bdff?s=47 wuct
October 23, 2016

Dive into React Performance

Three ways to improve the performance of a React app:

1. Reduce call to React.createElement
2. Avoid reconciliation
3. Avoid re-mounting

This talk explains why and how do we use these approaches.

672ba495b3eadfdb0daee60ed354bdff?s=128

wuct

October 23, 2016
Tweet

Transcript

  1. Dive into React Perf CT Wu, 2016 @ JSDC Twitter:

    wu_ct Github: wuct Email: wu.chingting@gmail.com
  2. Better performance leads to better user experience

  3. Use the production version of React

  4. Use a bundler <script src="path/to/react.min.js"></script> <script src="path/to/react-dom.min.js"></script> process.env.NODE_ENV = "production"

    Use pre-built files
  5. How does React work?

  6. createElement(View, {}, [ createElement(View), createElement(View) ]) <View> <View /> <View

    /> </View> { type: View, props: { children: [ { type: View }, { type: View }, ] } }
  7. ReactDOM.render( )

  8. setState()

  9. • Reduce call to React.createElement() • Avoid reconciliation • Avoid

    re-mounting
  10. render() { return ( <table> <thead> <tr> <th>Header 1</th> <th>Header

    2</th> </tr> </thead> <tfoot> <tr> <td>Footer 1</td> <td>Footer 2</td> </tr> </tfoot> <tbody> { // ... } </tbody> </table> ) } const headerAndFooter = <thead> <tr> <th>Header 1</th> <th>Header 2</th> </tr> </thead> <tfoot> <tr> <td>Footer 1</td> <td>Footer 2</td> </tr> </tfoot> render() { return ( <table> {headerAndFooter} <tbody> { // ... } </tbody> </table> ) }
  11. setState() bailout

  12. shoudComponentUpdate(nextProps, nextState) { if (/* You want to update */)

    { return true } return false }
  13. Pure Render Optimization shoudComponentUpdate(nextProps, nextState) { return ( !shallowEqual(nextProps, this.props)

    || !shallowEqual(nextState, this.state) ) } class extends React.PureComponent { // ... } or
  14. Anti Pure Render render() { return ( <PureComponent inlineFunc={() =>

    {}} funcBind={func.bind(this)} arrayLiteral={[]} newArray={map(…)} objectLiteral={{}} newObject={assign({}, …)} > <NestedChild /> </PureComponent> ) }
  15. Static View Optimization import StaticContainer from 'react-static-container' shoudComponentUpdate() { return

    false } or
  16. React Internal Bailout • Bailout when prevElement === nextElement •

    Don’t bailout when prevContext !== nextContext • React always create a new context • Don’t use setState() and getChildContext() in one component
  17. class extends React.Component { getChildContext() { return this.state } componentDidMount()

    { setInterval(() => this.setState({ time: this.state.time + 1 }) , 1000) } // ... }
  18. • Updating is faster than re-mounting • Don’t change the

    key or the type if you want to update
  19. render() { return isDarkTheme ? <DarkApp /> : <LightApp />

    } render() { <App dark={isDarkTheme} /> }
  20. render () { return ( <List> { data.map(item => <Item

    key={item.uniqueId} /> ) } </List> ) } render () { return ( <List> { data.map(item => <Item key={Math.random()} /> ) } </List> ) }
  21. React Perf Tool • Currently, only supports the development version

    of React • Perf.start() • Perf.stop() • Perf.printWasted() • Perf.printOperations()
  22. class Child extends React.Component { render() { return <div />

    } } class App extends React.Component { state = { title: 'Foo' } render() { return ( <div> {this.state.title} <Child /> </div> ) } }
  23. Perf.start() app.setState({ title: ‘bar’ }) Perf.stop() Perf.printWasted()

  24. class Child extends React.PureComponent { render() { return <div />

    } }
  25. Perf.start() app.setState({ title: ‘bar’ }) Perf.stop() Perf.printWasted()

  26. class App extends React.Component { state = { theme: 'light'

    } render() { return ( <div> { this.state.theme === 'light' ? <Light /> : <Dark /> } </div> ) } }
  27. Perf.start() app.setState({ theme: 'dark' }) Perf.stop() Perf.printOperations()

  28. class App extends React.Component { state = { theme: 'light'

    } render() { return ( <div> <Content theme={this.state.theme} /> </div> ) } }
  29. Perf.start() app.setState({ theme: 'dark' }) Perf.stop() Perf.printOperations()

  30. React Fiber • Is still experimental • Prioritization • Return

    multiple elements from render • Try it now: npm i react-dom@15.4.0-rc.4 import ReactDOMFiber from 'react-dom/fiber'
  31. Thanks! • Github: wuct • Twitter: wu_ct • wu.chingting@gmail.com