Slide 1

Slide 1 text

LIGHTNING Fast React Sia Karamalegos @thegreengreek

Slide 2

Slide 2 text

Who Am I? thegreengreek on Twitter and Medium siakaramalegos on GitHub

Slide 3

Slide 3 text

What are we going to talk about? 1. Why you should care about performance 2. Things you should always do 3. Things you should do only if you your app is too slow 4. The React Performance add-on

Slide 4

Slide 4 text

"53% of mobile site visits are abandoned if pages take longer than 3 seconds to load" DoubleClick by Google, 2016 https://www.doubleclickbygoogle.com/articles/mobile-speed-matters/

Slide 5

Slide 5 text

What about responsiveness?

Slide 6

Slide 6 text

What things should I always do?

Slide 7

Slide 7 text

Always use the production version of React in production! Or… Don’t ignore the warnings!

Slide 8

Slide 8 text

Automatic when using Create React App… • Development version is used when running $ npm start and then accessing the development build hosted at localhost:3000 • Production version is used when running $ npm run build and then using the production build found in the build/ folder

Slide 9

Slide 9 text

Declare the correct NODE_ENV in Webpack new webpack.DefinePlugin({ 'process.env': { NODE_ENV: JSON.stringify(process.env.NODE_ENV), }, }), ✔

Slide 10

Slide 10 text

Always use unique and stable keys! Again… Don’t ignore the warnings!

Slide 11

Slide 11 text

  • Sloth
  • Lemur
  • Koala
  • Kangaroo
  • Sloth
  • Lemur
  • Koala
  • Sloth
  • Lemur
  • Koala
  • Kangaroo
  • Sloth
  • Lemur
  • Koala
✘ ✔

Slide 12

Slide 12 text

  • Sloth
  • Lemur
  • Koala
  • Kangaroo
  • Sloth
  • Lemur
  • Koala
✘ Make sure keys are unique and stable!!

Slide 13

Slide 13 text

Always bind event handler functions before render! class MyComponent extends Component { handleClick(e) { // function content } render() { // Binding in render creates a brand new function // on every update, triggering a prop change. return this.handleClick()} /> } } class MyComponent extends Component { // Bind before render only creates function once // when instance of class is created. handleClick = (e) => { // function content } render() { return } } ✘ ✔

Slide 14

Slide 14 text

Never Mutate Objects! Your immutable friends include: ● The spread operator ● Object.assign() ● The array functions such as map() and filter(). Don’t use push() and pop()!! ● Immutable.js http://redux.js.org/docs/faq/ImmutableData.html#benefits-of-immutability http://reactkungfu.com/2015/08/pros-and-cons-of-using-immutability-with-react-js/ Further reading:

Slide 15

Slide 15 text

What things do I only do if DevTools show performance issues?

Slide 16

Slide 16 text

Avoid reconciliation when unnecessary. Use shouldComponentUpdate and/or PureComponent

Slide 17

Slide 17 text

shouldComponentUpdate() class CounterButton extends React.Component { constructor(props) { super(props); this.state = {count: 1}; } // If the color prop or the count in state do not change, then return false to avoid reconciliation shouldComponentUpdate(nextProps, nextState) { if (this.props.color !== nextProps.color) { return true; } if (this.state.count !== nextState.count) { return true; } return false; } render() { return ( this.setState(state => ({count: state.count + 1}))}> Count: {this.state.count} ); } } Warning: If `false`, none of the child nodes will be checked either!

Slide 18

Slide 18 text

PureComponent // Inheriting from PureComponent so all props and items in state will be shallow compared before updating class CounterButton extends React.PureComponent { constructor(props) { super(props); this.state = {count: 1}; } render() { return ( this.setState(state => ({count: state.count + 1}))}> Count: {this.state.count} ); } } Warnings: 1. Complex mutated states won’t trigger an update. Don’t mutate! 2. All subcomponents must be pure as well.

Slide 19

Slide 19 text

Never Mutate Data! Your immutable friends include: ● The spread operator ● Object.assign() ● The array functions such as map() and filter(). Don’t use push() and pop()!! ● Immutable.js http://redux.js.org/docs/faq/ImmutableData.html#benefits-of-immutability http://reactkungfu.com/2015/08/pros-and-cons-of-using-immutability-with-react-js/ Further reading:

Slide 20

Slide 20 text

Memoize any computed props in Redux mapStateToProps() Use the Reselect package

Slide 21

Slide 21 text

// Computed values passed into `connect()` // return a new object every time // Helper function for filtering things const getVisibleThings = (things, filter) => { switch (filter) { case 'SHOW_ALL': return things case 'SHOW_OPEN': return things.filter(things => things.open) case 'SHOW_CLOSED': return things.filter(things => !things.open) default: return things } } const mapStateToProps = (state) => { return { things: getVisibleThings(state.things, state.filter) } } connect(mapStateToProps)(SomeComponent) import {createSelector} from 'reselect' // Selector functions for non-computed properties const getThings = (state) => state.things const getFilter = (state) => state.filter // Create memoized selector function to return // computed object only if the inputs change const selectComputedData = createSelector( [getThings, getFilter], (things, filter) => { switch (filter) { case 'SHOW_ALL': return things case 'SHOW_OPEN': return things.filter(things => things.open) case 'SHOW_CLOSED': return things.filter(things => !things.open) default: return things } } ) const mapStateToProps = (state) => { return { things: selectComputedData(state) } } connect(mapStateToProps)(SomeComponent) ✘ ✔

Slide 22

Slide 22 text

Ugh… how do I find my problems?

Slide 23

Slide 23 text

Use Perf to profile your app! $ npm install react-addons-perf --save-dev

Slide 24

Slide 24 text

Perf in action Steal my widget from https://github.com/siakaramalegos/react_perf_widget

Slide 25

Slide 25 text

What if I need MOAR SPEED?

Slide 26

Slide 26 text

Learn about: Server-Side Rendering (SSR) Code Splitting with Webpack Progressive Web Apps (PWAs)

Slide 27

Slide 27 text

Summary ● Use the production version of React in production ● Use unique, stable keys in arrays and iterators ● Bind event handler functions before render ● Never mutate data Performance is important because both load time and responsiveness impact user experience. Alwaysdo: Only do if have problems: ● Avoid reconciliation when unnecessary ○ shouldComponentUpdate() ○ PureComponent ● Memoize computed props in Redux using Reselect

Slide 28

Slide 28 text

Resources you should totally check out…* Chrome DevTools Real time performance audit with Chrome DevTools, lecture and demo by Jon Kuperman Chrome DevTools docs by Google Analyzing Network Performance by Kayce Basques at Google Analyzing Runtime Performance by Kayce Basques at Google React + Redux Performance Optimizing Performance, Reconciliation, Performance Tools, PureComponent official docs by Facebook Never Bind in Render by Ryan Funduk Don't Use Bind When Passing Props by Dave Ceddia 9 things every React.js beginner should know by Cam Jackson - opinionated but some great tips Optimizing the Performance of Your React Application by Alex Sears, includes a tutorial How to Benchmark React Components: The Quick and Dirty Guide by Scott Domes Performance Engineering With React and A Deep Dive Into React Perf Debugging by Saif Hakim Reselect npm package, by the React Community React/Redux Performance Tuning Tips by Arik Maor * Don’t read this slide. It’s here for when you look at these slides later.

Slide 29

Slide 29 text

Thanks! thegreengreek on Twitter and Medium siakaramalegos on GitHub Slides: https://tinyurl.com/lightningreactconnect Give me feedback: https://tinyurl.com/siaspeaks