Overview

React native is based on JavaScript, the native part interacts with native thread through a bridge. We have three threads running the React native framework namely: UI thread, Shadow Tree thread and the JavaScript thread. Its architecture has two sections; the native part built on Java, Swift or Objective-C and React native part built on JavaScript. In this article, I will explore some of the common best practices you should consider to improve React Native performance.

1. Memory use

Native apps have a lot of unnecessary processes running in the background. Find these with the help of Xcode. The Xcode finds leaks which you should fix to improve performance. In Android Studio, there is an Android device monitor used to monitor leaks in apps. Using scrolling lists like,FlatListSectionList or isVirtualList a sure way to increase performance. Use the following code to monitor performance and to fix memory leaks.

Import PerfMonitor from ‘react-native/libraries/Performance/RCTRenderingPerf’;
perfMonitor.toggle();
PerfMonitor.start();
SetTimeout ( () => {
perfMonitor.stop();
}; 2000);
}; 5000);

2. Reduce Image Size and Image Caching

Images have high memory usage in react-native apps. Using large images in react-native apps have a negative impact on memory optimization. To get optimum results when dealing with images, ensure the use of small-sized images as much as possible. You may also use PNG formats as opposed to JPG image format. Finally, convert your images to web-P format whenever possible because of the following reasons:

  • WebP images speed up image loading time by 28%
  • Reduced codePush bundle size by 66%
  • Helps reduce iOS and Android binary size by 25%
  • Faster React-native JS thread
  • Smooth navigator transitions

Cache images locally to reduce the time taken to load images. As of now, React-native support caching on iOS only. See how in the following code:

<image
           source = {{
                   uri: 'https://facebook.github.io/react/logo-og.png',
                    cache: 'only-i- cached',
                }},
                 style = {{ width: 400, height: 400 }}
                   />

Now, image caching is an important step for improving the performance of your React Native app. It is also a known fact that React-Native supports image caching only for iOS platforms. Image caching can help in swifter loading of the images. App owners may also face the issue of failure of libraries when the preloaded images are not brought in when app is refreshed. This is called cache miss. Performance draining may also occur when cache logic operates towards the JS side.

3. Avoid Unnecessary Renders

Use PureComponentor,ShouldComponentUpdatePureComponent do a shallow comparison in props and state, while the lifecycleShouldComponentUpdate method is used in regular non-pure react components to cancel re-render by returning false in certain scenarios.

sample code

class myComponent extend React-Pure component {

class myComponent extends React.Component {
//
}
shouldComponentUpdate (nextPros, nextState) {
if( this.props.firstProp === nextProps. firstProps &&
this.props.secondProp === nextPorps.secondProp) {
return false;
}
return true;
}
//
}

4. Don’t update state or dispatch actions in componentWillUpdate

You should use a lifecyclecomponentWillUpdate method to prepare for an update, not to trigger another one. If your aim is to set a state,  you should do that insteadcomponentWillReceiveProps. And prefer tocomponentDidUpdate dispatch any redux actions over tocomponentWillReceiveProps be safe.

5. Bind early and don’t create functions inside render.

You should do this…

class MyComponent extends React.PureComponent {
  constructor(props) {
    super(props);
    this.doWork = this.doWork.bind(this);
  }

doWork() {
    // doing work here.
    // this.props.dispatch....
  }
  render() {
    return <Text onPress={this.doWork}>Do Some Work</Text>
  }
}

Avoid doing this inside render.

<Text onPress={ () => this.doWork() }>Do Some Work</Text>

Also, avoid this.


<Text onPress={ this.doWork.bind(this) }>Do Some Work</Text>

Because render is often called, and every time you do any of the two things above, it creates a new function, it is not recommended that way. If you want to pass arguments to doWork function, create a child component and pass the function as a prop, simple.

<child arg1={arg1}></child>

And in the child component.

doWork() {
  console.log(this.props.arg1);
}
render() {
  return <Text onPress={this.doWork}>Do Some Work</Text>
}

If you think creating a component is an over head thing, then you might want to use a closure like the following in which a function is created on each re-render.

doWork = (param) => () => {
 console.log(param)
}
<Text onPress={this.doWork(someVarParam)}Do Some Work With Args</Text>

Weigh between your readability and performance requirements in such cases for optimum satisfaction.

6. Use key attribute on list items

List is something commonly used in apps. You should specify a unique key for each list item, so that react will not re-render every item when an item is added or removed from the list. A unique key in every list item saves react from re-rendering it again.

Sample code

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

7. Eliminate Unnecessary Features

Consider the architecture of your app when you experience slow page loads. Eliminate any unnecessary data, tabs, navigations, controls or animations, they all add up to the page load time. Consider displaying items only useful to the user. All the unnecessary items on your app add load times and clutter the user experience of your app, so consider reducing apps’ features without decreasing the UX. It is also important to design your apps to fit the designs of various devices.

Conclusion

There are other issues that may affect the react native performance, I only discussed seven of them in this article. I recommend you chose a way to increase performance without compromising the functionality of the app and the user UX.