Building High Performance Apps with React

I'm Sanket

    GeekyAnts

We are the ones behind

NativeBase

BuilderX

/@sanketsahu

React

Built to provide better performance

React is more than just Web

It can also be used for Mobile and Desktop

BuilderX

Building Highly Interactive Apps

Keeping the app performant is crucial

2 Steps to build High Performance Apps

  • Measure

  • Improve

Measure

Chrome Developer Tools

  • Timeline View
  • Profiles View

Timeline View

Profiles View

react-addons-perf

  • Gives overall app performance.
  • Tells you where to put optimization hints.
  • Works only for development build.
  • Not supported from React 16.

React Performance Tools

import Perf from 'react-addons-perf'; // ES6
var Perf = require('react-addons-perf'); // ES5 with npm

For when you need high performance out of your app, use React's shouldComponentUpdate() to add optimization hints.

Getting Measurements

  • start()
  • stop()
  • getLastMeasurements()

Debugging and Measuring

Redux Dev Tools to debug mobx-state-tree

import { createStore } from "redux";
import { onSnapshot } from "mobx-state-tree";

export default class ReduxDevTools {
  static logger(state = {}, action: { state: any; type: string }) {
    return action.state;
  }

  static init(state: any) {
    const store: any = createStore(
      ReduxDevTools.logger,
      (window as any).__REDUX_DEVTOOLS_EXTENSION__ &&
        (window as any).__REDUX_DEVTOOLS_EXTENSION__()
    );

    onSnapshot(state, snapshot => {
      store.dispatch({ type: "LOG", state: snapshot });
    });
  }
}

Electron DevTools Installer

  • Chrome Extensions
  • Redux DevTools
  • React Perf
  • React Developer Tools

mobx-react-devtools

  • Measure re-renders
  • List down observables
  • Log actions and reactions

Also...

Measure time take for various actions using console.time.

Update root MST store in window on every snapshot  so that we can view the state tree from Chrome console.

Created a HOC which gets the list of observables for the input components and finds their path in root MST store.

Used MobX spy.

We realized that our render() was taking too long.

Why?

We were doing two things at once

  • Build the UI
  • Compute coordinates

JavaScript is Single Threaded

Multi-Threading

  • Minimized the computation in render().
  • Moved it to another thread by spawning a new Unix thread.
  • This actually worked as a boon for separation of concerns.

JavaScript is immutable

Improve

State Management

Redux

Mobx

Redux

mobx-state-tree

Our own state management solution

Redux

  • There were too many connected components.
  • mapStateToProps was being hit for every connected component.
  • We were using selectors without reselect.

MobX

  • Couldn't find a good pattern.
  • Undo/redo was much more difficult than in  Redux/MST.

mobx-state-tree (MST)

Snapshot generation is an overhead

My Experience of building BuilderX

AST Manipulation

For long lists like Iconlist, we implemented lazy loading with infinite scrolling

Artboard

credits: Brendan Eich

Thank you!

/@sanketsahu

Building High Performance Apps using React

By sanketgeekyants

Building High Performance Apps using React

  • 541