Codementor Events

How to Improve the Performance of React Native Application

Published Jan 03, 2019
How to Improve the Performance of React Native Application

React Native App Architecture
React Native is based on JavaScript, in which the React Native part interacts with the Native thread through a bridge.

Mainly we have 3 main threds that runs the framwork. UI thread, Shadow Tree Thread, and Javascript Thread or native thread.

so the React Native architecture has two significant sections:

  1. Native Part built on Java, Swift, or Objective-C.

  2. React Native part built on JavaScript.

To improve your React Native application performance, here are some common practices, which will surely help you a lot during the production of a complex project

Memory Issue

This is one the most common issues for native applications with a lot of unnecessary processes running in the background.

With the use of Xcode you can find a leaks

Go to XCode → Product → Profile (⌘ + i)

After that shows you all template choose leaks.

With the use of Android Studio can Find a leaks

Run React Native app normally (react-native run-android)
Run Android Studio

On the menu,
click Tools → Android → Enable ADB Integration
Click Tools → Android → Android Device Monitor
When Android Device Monitor shows up, click Monitor → Preferences
Perf Monitor is a good choice to use for android leaks monitoring.

Import PerfMonitor from 'react-native/Libraries/Performance/RCTRenderingPerf';
PerfMonitor.toggle();
 PerfMonitor.start();
 setTimeout(() => {
   PerfMonitor.stop();
 }, 20000);
}, 5000);

To fix memory leaks in native applications, you can use scrolling lists such as FlatList, SectionList, or VirtualList instead of Listview.

Scrolling list also helps in smoothing the infinite scroll pagination, so if you’re building an application with a pull to refresh feature, and large data points, then it is advisable to consider it.

Reduce Image size

Images is a big issue for high memory usage. Image optimization is very impotent in React Native application.

  1. Use smaller sized images.
  2. Use PNG as opposed to JPG.
  3. Convert your images to WebP format.

Why WebP Format you may ask ?

WebP images can speed up your image loading time to 28%.
Reduced CodePush bundle size by 66% with .webp format
Helps to reduce iOS and Android binary sizes by 25% with.webp format
React Native JS Thread feels so much faster
Navigator transitions are so much smoother

Cache the images locally

Image caching is important for loading images faster. As of now, React Native only provides image caching support on iOS.

This is a quick example, as seen in the docs (IOS only)

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

For Android, there are some npm libraries available out there that helps to solve the image caching issue. Unfortunately, they don’t offer the best performance.

Avoiding Unnecessary Renders

Overriding a Component Update:

One of the most common problems is not to implement this diff state, lifecycle and props yourself for the first- you should first ensure that if your components should update or not, and make sure to not pass too much needless work to Reconciler, probably it will drop your JS thread’s FPS. Though outspread from PureComponent instead of Component.

shouldComponentUpdate( nextProps, nextState ) { 
  if(nextProps.isUpdated == this.props.isUpdated) {
          return false; 
        } else {
    return true; 
        }
  }

shouldComponentUpdate should always return a boolean  an answer to the question,
“should I re-render?”
Yes, it is advisable to have little component.

Using PureComponent :

PureComponent in React don’t have a state, they just render your component based on the data passed via props. It re-renders only if props change.

shouldComponentUpdate life-cycle method is used in regular non pure React Component to cancel the re-render by returning false in certain scenarios.

class MyPureComponent extends React.PureComponent {
  render() {
    return (
                     Hello World
                )
        }
}

Optimizing JSON Data

Mobile applications always require load resources from a service or remote URL and to accomplish such actions, programmers make fetch requests to pull data from that server.

The fetched data from private as well as public APIs returns in a JSON form that has some sort of compound nested objects.

Usually, most of the programmers store the same JSON data for local offline access and the performance suffers because JS applications render JSON data slowly. So, what I would like to advise you is convert raw JSON data in simpler objects before rendering.

fetch('SomeURL', {
 method: 'POST',
 headers: {
    Accept: 'application/json',
   'Content-Type': 'application/json',
 },
 body: JSON.stringify({
   firstParam: 'yourValue',
   secondParam: 'yourOtherValue',
 }),
}).then((response) => response.json())
  .then((responseJson) => {
       // Use JSON.parse Method To Convert Response in Object 
       var response = JSON.parse(responseJson);
       return response;
     })
   .catch((error) => {
     console.error(error);
   })

Use NativeDriver Animation

Animations in React Native look good and are easy to create. As animated library lets you sanction native driver, it will send the animations over the bridge to the native side before the animation starts. Animations will execute the main thread independently of a blocked JavaScript thread, it will result in a smoother experience and fewer frame drops. Set use Native Driver to the animation configuration.

This is how a regular animation performs;

JavaScript driver uses requestAnimationFrame to execute on every frame
Intermediate values are calculated and passed to the View
The View is updated using setNativeProps
JS sends this changes to the native environment through the bridge
Native updates UIView or android.View
But, Native Driver Animation working like this.

The native animation driver uses CADisplayLink or android.view.Choreographer to execute on every frame
Intermediate values are calculated and passed to a view
The UIView/android.View is updated
Example :

  Animated.timing(
            this.state.fadeAnim, {
            toValue: 1,
            userNativeDriver: true,
           }
        ).start()

< Animated.ScrollView // <-- Use the Animated ScrollView wrapper
  scrollEventThrottle={1} // <-- Use 1 here to make sure no events are ever missed
  onScroll={Animated.event(
    [{ nativeEvent: { contentOffset: { y: this.state.animatedValue } } }],
    { useNativeDriver: true } // <-- Add this
  )}
>
  {content}
< /Animated.ScrollView >

Reduce Application Size

In React native you use external libraries and component form libraries so it impact in application size.

To reduce the size, you have to optimize the resources, use ProGaurd, create different app sizes for different device architectures, and make sure to compress the graphics elements, i.e. images.

You can follow below common practices for reducing app size:

Move components from the native realm to the React Native realm

The components on the JavaScript side use a bridge to communicate with the Native side.

Reduce the load on the bridge and improve the app’s performance.
Check the stability of open source libraries before you use them.

Boilerplate codes in libraries often slow down the rendering performance.
Some components make heavy use of message queues while communicating with the Native side, so you should not pass them on the main thread.

Discover and read more posts from jigar yadav
get started
post commentsBe the first to share your opinion
Andrew McCullough
5 years ago

“PureComponent in React don’t have a state, they just render your component based on the data passed via props” - that is incorrect, a PureComponent can/does have state. I think you are confused with a stateless / functional component

Noman Ansari
3 years ago

yes purecomponent definitely contains the state but Pure Component handles the shouldcomponentupdate() method itself and reduces un necessary renders.
either the component contain state or props purecomponent check prev and updated values of state / props and if values changed it will render otherwise it will not render.
the comparison is done by shallow comparison, which in not good if you have objects or Arrays,
then it will behave completely different.
inShort if your Components state or props contain var like number and string you can use it. and surely you will see the difference.
if you have Arrays, list, Nested Objects it wont work as expected

Show more replies