In my previous article I have talked about hacking event loop for improving performance of your app. Your goal is to retain 60 FPS throughout. All of that applies to react or react native app as well. So if you haven’t read it yet, maybe its the right time to do so.

Here are few things you can do if you are using react or react native, to maintain higher FPS.

1. Use PureComponent or shouldComponentUpdate

PureComponent in react do a shallow comparison of props and state before updating the component. It re-renders only if there is shallow change in props or state.

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

Following two code samples do the same thing.

class MyComponent extends React.PureComponent {

//

} class MyComponent extends React.Component {

//

shouldComponentUpdate(nextProps, nextState) {

if(this.props.firstProp === nextProps. firstProp &&

this.props.secondProp === nextProps.secondProp) {

return false;

}

return true

}

//

}

Both of the above examples can help you save some wasted renders. First example implements the shouldComponentUpdate logic for you already. The second example gives you a bit more control. You can maintain state in component and stop re-rendering if the state doesn’t change. Like this

class MyComponent extends React.Component {

shouldComponentUpdate(nextProps, nextState) {

if(this.state.isLoading === nextState. isLoading) {

return false;

}

return true

}

}

2. Use key attribute on list items

List is the most commonly used thing in any application. If you don’t specify unique key for every list item, react will re-render every item when any item is added or removed from the list. Having a unique key on every list item, saves react re-rendering it again.

class MyComponent extends React.PureComponent {

render() {

return this.props.data.map((item, i) => {

return <Text key={item.id}>{item.title}</Text>

});

}

}

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

Do this

class MyComponent extends React.PureComponent {



constructor(props) {

super(props);

this.doWork = this.doWork.bind(this);

} doWork() {

// doing some work here.

// this.props.dispatch....

}



render() {

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

}



}

Don’t do this inside render.

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

or

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

Because render is called very often and every time you do any of the two things above, a new function is created.

If you want to pass arguments to doWork function, you might need to create a child component and pass the function as a prop.

<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 creating component is an over head, then there is a little performance trade off always. You might use a closure like following. A function is going to be created on each re-render.

doWork = (param) => () => {

console.log(param)

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

Weigh your readability and performance requirements in such cases.

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

componentWillUpdate lifecycle method is used to prepare for an update, not trigger another one. If you want to set state, do that in componentWillReceiveProps instead. And prefer componentDidUpdate to dispatch any redux actions over componentWillReceiveProps.

5. Use VirtualizedList, FlatList and SectionList for large data sets.

As per react native docs, VirtualizedList, FlatList and SectionList are performant interface for rendering lists, since they use lesser memory footprint. So if you have a list with hundreds of rows, not all of them are loaded on to the screen until you scroll down.

VirtualizedList is the base for both FlatList and SectionList. And if you have immutable data set, you should use VirtualizedList directly.

6. Use Perf monitor to watch FPS

Open up developer tools and enable perf monitor. Now when you start interacting, navigating or scrolling your app, you might see FPS drops sometimes. And mostly its on JS thread and not on the native UI thread. So start looking for the pain points, where FPS is dropping. You might be setting state or dispatching redux actions at wrong place. Or doing too much synchronous work on the JS thread.

Will share more advanced techniques in my next article about react native. You may follow me to get updates when new stories are published :)

If you want add anything, please post it in comments section.