Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Dive into React Performance

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.

wuct

October 23, 2016
Tweet

More Decks by wuct

Other Decks in Programming

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