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

Made with Slides.com