React Native performance optimization (official website guide handling)

React Native performance optimization (official website guide handling)

I was writing React-Native recently and took advantage of the fact that the requirements were almost completed in these two days, and I practiced some optimization items.

Recorded here

Life sucks

Performance

Refer to React native Performance

View performance

Open the developer menu (shaking the phone to open) Open, Show Perf Monitoryou can see the display box below

The frame number of UI and JS is kept stable at 60, which is the optimal situation.

JS single thread

All event processing, API requests, and other operations are on this thread. When there is a this.setStatelarge amount of data, state changes will cause re-render . During this period, all animations controlled by JavaScript will freeze and drop frames.

For example, when switching routes, the number of frames will jitter significantly. At this time, if there are some componentDidMountoperations being performed, the routing transition animation will be very stuck. (I will introduce some solutions you can try later

The performance of the development environment is worse than that of the production environment

In the development environment, the framework will have many other operations such as warning error output, type detection and so on.

If you want to test performance, it is best to test in the releasepackage. This is more precise.

Remove console.* from production environment

During development, there are many console.*instructions to help debugging. And some dependent libraries will also have console.*these statements, which is a great consumption for the JavaScript thread. It can be removed in the production environment through Babel console.*.

  • Install plugin

    npm i babel-plugin-transform-remove-console --save-dev

  • Configuration .babelrcfile

    {
      "env": {
        "production": {
          "plugins": ["transform-remove-console"]
        }
      }
    }
     

Used when processing large data lists<FlatList/>

FlatListComponents more suitable to show a long list, and specify the appropriate getItemLayoutmethod getItemLayoutskips layout calculation when rendering Item, directly given configuration (see details link )

Rely on lazy loading

Before the framework executes the written business code, it needs to load and parse the code in memory. The larger the amount of code, the more time-consuming process, resulting in slower rendering of the first screen. And often there are some pages or components that will not be accessed by users at all. At this time, it can be optimized by lazy loading.

The official website gives examples

VeryExpensive.js

import React, { Component } from 'react';
import { Text } from 'react-native';
//... import some very expensive modules

//You may want to log at the file level to verify when this is happening
console.log('VeryExpensive component loaded');

export default class VeryExpensive extends Component {
  //lots and lots of code
  render() {
    return <Text>Very Expensive Component</Text>;
  }
}
 

Optimized.js

import React, { Component } from 'react';
import { TouchableOpacity, View, Text } from 'react-native';

let VeryExpensive = null; //

export default class Optimized extends Component {
  state = { needsExpensive: false }; // 

  didPress = () => {
    // 
    if (VeryExpensive == null) { // 
      VeryExpensive = require('./VeryExpensive').default;  // 
    }

    this.setState(() => ({
      needsExpensive: true, // re-render
    }));
  };

  render() {
    return (
      <View style={{ marginTop: 20 }}>
        <TouchableOpacity onPress={this.didPress}>
          <Text>Load</Text>
        </TouchableOpacity>
        {this.state.needsExpensive ? <VeryExpensive/> : null}
      </View>
    );
  }
}
 

Optimize component rendering times

React will re-render the component when the stateincoming internal or external propschanges change. If there are a large number of components to be re-rendered in a short time, it will cause serious performance problems. Here is a point that can be optimized.

  • Use the changes PureComponent that let the components compare propsby themselves to control the number of renderings. In practice, this controllable method is more reliable than pure functional components. Or Component using shouldComponentUpdate a method to control the update component is determined by the conditions/re-rendering.
  • PureComponent Pay attention to the shallow comparison state of this component when using . If props there are a large number of reference type objects, the internal changes of these objects will not be compared. So try to avoid complex data structures when writing code
  • Fine-grained components, split dynamic/static components. It needs to be unified planning after the project is stable and has a certain scale.
  • Learn **immutable-js**

Asynchronous, callback

JavaScript is single-threaded, and you must make good use of its asynchronous features and some hook callbacks.

The above-mentioned example, when the route switching componentDidMount operation leads to Caton, may be used herein InteractionManager.runAfterInteractions() operation to be performed into runAfterInteractions the callback executed.

componentDidMount() {
	InteractionManager.runAfterInteractions(() => {
        //your actions
	})
}
 

Note that InteractionManager Shi will trigger after listening to all the animation/interaction is complete runAfterInteractions callback, if there are some long animations or interactive project, you may encounter long waits. Therefore, due to the InteractionManager uncontrollable, use the time to adjust according to the actual situation.

In some of the react-native animation feedback, such as TouchableOpacity when touched will respond onPress and will change its transparency, this process if onPress there is a complex operation, is likely to cause the transparent component feedback Caton, time may be onPress in wrapped in operation requestAnimationFrame of. Here is a my practice (using styled-component)

import styled from 'styled-components'

export const TouchableOpacity = styled.TouchableOpacity.attrs({
  onPress: props => () => {
    requestAnimationFrame(() => {
      props.onPressAsync && props.onPressAsync()
    }, 0)
  }
})``
 

Here the onPress change in the requestAnimationFrame execution of callback onPressAsync passed in operation.

Similarly, also in FlatList the onReachEndpractice of this operation to avoid iOS Caton performed the operation when scrolling rebound.

Above, I have recorded some practical optimization items written in React-Native recently.

At last

The road is long and long, I will search up and down

May love & peace be with you

reference

Author: Roy Luo

This link: React Native performance optimization (official website guide handling)