The performance problem of React Native applications is a big one. Because if the lag, slow during use, users will definitely not want to touch our application for the second time. In this article, we will learn together some ways to improve the performance of app
Do not handle a time-consuming job in the constructor
If you do something too time-consuming in the constructor, the component class initialization will take a long time, so the render view will also slow down => of course our app will look jerky.
1 2 3 4 5 6 7 8 9 | <span class="token keyword">class</span> <span class="token class-name">MyFavoriteComponent</span> <span class="token keyword">extends</span> <span class="token class-name">Component</span> <span class="token punctuation">{</span> <span class="token function">constructor</span> <span class="token punctuation">(</span> props <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">super</span> <span class="token punctuation">(</span> props <span class="token punctuation">)</span> <span class="token function">performSomeLongRunningOperation</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
Note: Not only in the constructor, but we should not perform a task for too long in componentWillMount
, we should put them in componentDidMount
, when the view has been rendered.
Do not use functional props
We consider the following example
1 2 3 4 5 6 7 8 9 10 11 12 13 | <span class="token keyword">class</span> <span class="token class-name">MyComponent</span> <span class="token keyword">extends</span> <span class="token class-name">Component</span> <span class="token punctuation">{</span> <span class="token function">render</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">(</span> <span class="token operator"><</span> SomeComplexComponent prop1 <span class="token operator">=</span> <span class="token string">"Hey, I'm prop1"</span> prop2 <span class="token operator">=</span> <span class="token string">"Hey, I'm prop2"</span> onPress <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token punctuation">(</span> id <span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">doSomething</span> <span class="token punctuation">(</span> id <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token operator">/</span> <span class="token operator">></span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
We can see that the above code may be very normal, but when each render of the MyComponent above, SomeComplexComponent will also be re-rendered, even though their props have not changed. The main reason is that there is an arrow function
in onPress
. Every time the render()
of MyComponent is called, a new onPress
reference will be created, which will cause SomeComplexComponent to be re-rendered. Obviously this is not necessary.
To avoid that, we will do the following
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | <span class="token keyword">class</span> <span class="token class-name">MyComponent</span> <span class="token keyword">extends</span> <span class="token class-name">Component</span> <span class="token punctuation">{</span> <span class="token function">render</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">(</span> <span class="token operator"><</span> SomeComplexComponent prop1 <span class="token operator">=</span> <span class="token string">"Hey, I'm prop1"</span> prop2 <span class="token operator">=</span> <span class="token string">"Hey, I'm prop2"</span> onPress <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token keyword">this</span> <span class="token punctuation">.</span> doSomething <span class="token punctuation">}</span> <span class="token operator">/</span> <span class="token operator">></span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function-variable function">doSomething</span> <span class="token operator">=</span> <span class="token punctuation">(</span> id <span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">this</span> <span class="token punctuation">.</span> <span class="token function">setState</span> <span class="token punctuation">(</span> <span class="token punctuation">{</span> selectedId <span class="token punctuation">:</span> id <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
very simple, right
Use PureComponent or shouldComponentUpdate
When using PureComponent
, when there are no changes to the state or props, the component will not be re-rendered.
If you want control over props and states, use shouldComponentUpdate
1 2 3 4 | <span class="token function">shouldComponentUpdate</span> <span class="token punctuation">(</span> nextProps <span class="token punctuation">,</span> nextState <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">(</span> nextProps <span class="token punctuation">.</span> title <span class="token operator">!==</span> <span class="token keyword">this</span> <span class="token punctuation">.</span> props <span class="token punctuation">.</span> title <span class="token operator">||</span> nextProps <span class="token punctuation">.</span> description <span class="token operator">!==</span> <span class="token keyword">this</span> <span class="token punctuation">.</span> props <span class="token punctuation">.</span> description <span class="token operator">||</span> nextProps <span class="token punctuation">.</span> imageUrl <span class="token operator">!==</span> <span class="token keyword">this</span> <span class="token punctuation">.</span> props <span class="token punctuation">.</span> imageUrl <span class="token punctuation">)</span> <span class="token punctuation">}</span> |
As in the example above, the component will be title, description, imageUrl
when one of the 3 props title, description, imageUrl
changes.
Note: You can only use one of the two methods above for the same component
Use Native Drive for Animations in the app
In react we have 2 types of animations:
- JS based: we will do everything through the JS thread and only dispatch the last frame to the native.
- Purely Native: we will give all animation information to the native, so the processing will be done directly via native => so it will definitely be smoother.
For example:
1 2 3 4 5 6 7 | Animated <span class="token punctuation">.</span> <span class="token function">timing</span> <span class="token punctuation">(</span> zoom <span class="token punctuation">,</span> <span class="token punctuation">{</span> toValue <span class="token punctuation">:</span> <span class="token number">1</span> <span class="token punctuation">,</span> duration <span class="token punctuation">:</span> ScoreConst <span class="token punctuation">.</span> <span class="token constant">DURATION</span> <span class="token punctuation">.</span> <span class="token constant">OUT</span> <span class="token operator">/</span> <span class="token number">2</span> <span class="token punctuation">,</span> easing <span class="token punctuation">:</span> Easing <span class="token punctuation">.</span> ease <span class="token punctuation">,</span> useNativeDriver <span class="token punctuation">:</span> <span class="token boolean">true</span> <span class="token comment">// thêm dòng này nhé</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> |
Some other notes
- Let’s use
Flatlist
instead ofListView
- Remove the console when released, you can use the transform-remove-console to automatically delete all logs, including the library log.
- Only import type libraries when needed.
- Sometimes we use native tools to see our app’s CPU, memory, Flow View, etc.