Leverage your React Native App

JakartaJS 24・1・2018

My Background

Alfian Busyro (Aru)

9+ years (Salary-man)

iOS Developer

Past

Present

Developer MasterClass Trainer

Consultant

Mobile App Developer

Intro to React Native Rendering

Paimin

Paijo

They Launched a Mobile App

Min: Jo, Kenapa aplikasi kita lemot ?

Jo: Karena kita pakai React Native

Paimin

Paijo

Mukidi

Please introduce Yoga

cross platform layout engine

 

  • C under the hood so your code moves fast
  • Flexbox Styling
  • Battle tested in popular frameworks like React Native.

https://facebook.github.io/yoga/

React Native is Fast

Limiting Re-render

Guard  with shouldComponentUpdate

shouldComponentUpdate(nextProps, nextState) {
  return (
    (!isEqual(this.props.a, nextProps.a)) ||
    (!isEqual(this.state.data, nextState.data))
  )
}

Combine with Lodash isEqual

Don't compare:

  • Functions
  • Constants
  • All props and states

PureComponent  FTW!

// From

export default class AwesomeComponent extends React.Component {

// To

export default class AwesomeComponent extends React.PureComponent {

Don't :

  • Pass all data to PureComponent props
  • Complex state or props data
  • inline object data ( since {} !== {} )

 Use key attribute on list items

class MyComponent extends React.PureComponent {
  render() {
    return this.props.data.map((item, i) => {
      return <Text key={item.id}>{item.title}</Text>
    });
  }
}

Rendering Blocking

What cause

Rendering Blocking

  • Big process in constructor
  • Another big process in componentWillMount
  • Yet another big process in render
  • Your async process is also big

JS Thread is not completely Async

export default class AwesomeComponent extends Component {

  glamorousAsyncProcess() {
    // redux action that remains forever
  }

  constructor() {
    super()
    // don't
    glamorousAsyncProcess()
  }

  componentWillMount() {
    // don't
    glamorousAsyncProcess()
  }

  async populateUser() {
    // populate 1M Users
    await this.props.populateMillionUsers()
  }

  render() {
    //don't
    populateUser()
    
    return(
      <View>
        <Text>
          Hello World! with heavy process on the back
        </Text>
      </View>
    )
  }

}

How to Prevent

Rendering Blocking

  • Do big process in componentDidMount (Including your glamorous Redux action)
  • Don't do big logic process in render
  • Bind early and don’t create functions inside render
class AwesomeComponent extends Component {

  glamorousAsyncProcess() {
    // redux action that remains forever
  }

  constructor() {
    super()
    this.viewContacts = this.viewContacts.bind(this)
  }

  componentDidMount() {
    // do
    glamorousAsyncProcess()
  }

  viewContacts() {
    // Show Contact List
  }

  render() {
    
    return(
      <View>
        <Text>
          Hello World! with heavy process on the back
        </Text>
        <TouchableOpacity onPress={this.viewContacts} >
          <Text>Press Me!</Text>
        </TouchableOpacity>
      </View>
    )
  }
}

List

FlatList better than ListView

Advantages:

  • PureComponent
  • Only render visible view
  • Pull to refresh

Common issue:

  • multiple onPress function
  • pass big data to renderItem Component props

 

SectionList better than ScrollView

Advantages:

  • PureComponent
  • Only render visible view
  • Pull to refresh
  • Section header

Common issue:

  • multiple onPress function
  • pass big data to renderItem Component props

 

Advance Optimization

requestAnimationFrame & next-frame

Goal: deferred process until the next paint on JS Thread

https://github.com/corbt/next-frame

Codes

import nextFrame from 'next-frame';

// ...

for (let recording of recordingsJSON) {
  await nextFrame(); // This is all we need to add!
  mergeRecordingToLocalDatabase(recording);
}

Codes

let setDefaultAddressInRedux = async () => {
  await nextFrame()
  setTimeout(() => {
    self.props.setDefaultAddressInRedux(selectedDefaultAddress)
  }, 0)
}
setDefaultAddressInRedux()

why-did-you-update to keep eye on render

https://github.com/maicki/why-did-you-update

Show Perf Monitor

Best: 60 FPS (Apple)

Thank You!

alfian@payfazz.com / arufian703@gmail.com

arufian_b

Inquiry

Leverage Your React Native App

By Alfian Busyro

Leverage Your React Native App

Many people saying that React Native app is slower than Native App. That's not true, we can make it faster than any other native app. Here are the tricks.

  • 1,297