React Native is known for its amazing performance in most of the applications: 60 FPS
Stateful vs Stateless vs React.PureComponent
- “Stateless” is better than regular “Stateful” component
- Render speed is quicker because they don’t require some life cycles hooks (mounting, unmounting, updating)
- Pure functions provide a lot of benefits
- Predictable UI
- Easy tracking of user behavior
- Functional components are faster, but in most cases are outperformed by class components extending “React.PureComponent” when props are shallowly equal
https://github.com/reactjs/reactjs.org/issues/639#issuecomment-367858928
“StyleSheet” or inline styles
Create a “StyleSheet” from Style object is better
- Makes it possible to refer to it by ID instead of creating a new style object every time
- Allows you to send the style only once through the bridge. All subsequent uses are going to refer an ID (not implemented yet)
- Inline style
- lose the optimizations when it comes to style-caching. Most likely, on every re-render, styles will be recalculated and sent over the bridge again
Arrow function or binding
Bind the function inside constructor is performance-wise
this.expandOrCollapse = this.expandOrCollapse.bind(this);
Render function
Creating variables inside the render function will slow your application down. Sometimes, patterns can sacrifice performance a little and sometimes they cannot.
shouldComponentUpdate (should be replaced by PureComponent)
To find out the necessary steps to reduce the DOM operations, React has to fire the render methods of all the components and compare the results with the previous ones.
If our render methods do complex operations, React will take some time to figure out that no operations have to be done, which is not optimal.
We surely want our components to be simple, and we should avoid doing expensive operations inside the renderer. However,
sometimes we simply cannot manage this and our applications become slow, even if the DOM is not touched at all.
React is not able to figure out which components do not need to be updated, but we have a function that we can implement to tell the library whether to update a component or not.
The method is called shouldComponentUpdate, and if it returns false, the component and all its children’s render methods are not called during an update of its parents.
class List extends Component { constructor(props) { super(props); this.state = { items: ['foo', 'bar'] }; this.handleClick = this.handleClick.bind(this); } shouldComponentUpdate(nextProps, nextState) { return this.state.items !== nextState.items; } handleClick() { const items = this.state.items.slice(); items.unshift('baz'); this.setState({ items }); } render() { return ( <div> <ul> {this.state.items.map(item => <li key={item}>{item}</li>)} </ul> <button onClick={this.handleClick}>+</button> </div> ); } }
We return true only if the items are changed
PureComponent
Checking if all the props and all the state attributes are changed is a boring job, and it is sometimes hard to maintain the complex shouldComponentUpdate implementations, especially when the requirements change frequently.
For that reason, React gives us a special component from which we can inherit and which implements a shallow comparison of all the props and the state attributes for us.
Using it is pretty straightforward; we just have to extend React.PureComponent instead of React.Component when we create our component classes.
It is important to notice that the shallow comparison, as the name suggests, does not check for deep and nested properties in objects, and it can sometimes give unexpected results.
Don’t make PureComponent less effective, such as generating new functions inside the render method or using constant as props.
Immutability when using PureComponent
Issue
The only problem is that PureComponent uses a shallow comparison method against the props and state. A shallow comparison cannot find mutation on the properties and the components never get re-rendered, except when the object itself changes.
One way to solve this issue is using immutable data: Data that, once it gets created, cannot be mutated.
Investigation
For example, we can set the state in the following mode:
const obj = this.state.obj; obj.foo = 'bar'; this.setState({ obj });
Reason
Even if the value of the foo attribute of the object is changed, the reference to the object is still the same and the shallow comparison does not recognize it.
Solution
What we can do instead is create a new instance every time we mutate the object, as follows:
const obj = Object.assign({}, this.state.obj, { foo: 'bar' }); this.setState({ obj });
With ES6 and Babel, there is another way to express the same concept in a more elegant way, and it is by using the object spread operator:
const obj = { ...this.state.obj, foo: 'bar' }; this.setState({ obj });
Flatlist
Key
Apply key property into children of list. The key has to only be unique among its siblings, it does not have to be unique globally.
PureComponent
If you create your FlatList
item as PureComponent
, you can see lot of improvement. It will not re-render items until data has been changed.
removeClippedSubViews
This is a special performance property exposed byRCTView
and is useful for scrolling content when there are many subviews, most of which are offscreen. For this property to be effective, it must be applied to a view that contains many subviews that extend outside its bound. The subviews must also haveoverflow: hidden
, as should the containing view (or one of its superviews).
Leave a Reply