React itself has used techniques to optimize the UI rendering process, but depending on the complexity and business of the app, React itself cannot adequately optimize the rendering process; So we need to implement techniques to improve the performance of the app.
Use shouldComponentUpdate
Usually child components always re-render according to the parent component even though the props passed to these child components have not changed.
In fact, we only need to render the child components only when the props passed change, to do this we need to implement the shouldComponentUpdate
function like so:
1 2 3 4 5 6 7 |
<span class="token function">shouldComponentUpdate</span> <span class="token punctuation">(</span> <span class="token parameter">nextProps <span class="token punctuation">,</span> nextState</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> nextProps <span class="token punctuation">.</span> data <span class="token operator">===</span> <span class="token keyword">this</span> <span class="token punctuation">.</span> props <span class="token punctuation">.</span> data <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token boolean">false</span> <span class="token punctuation">;</span> <span class="token comment">// skip re-render component</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> <span class="token boolean">true</span> <span class="token punctuation">;</span> <span class="token comment">// re-render component (default)</span> <span class="token punctuation">}</span> |
In most cases, instead of implementing the shouldComponentUpdate
manual function, it is possible to inherit a component class from PureComponent
instead of Component
.
PureComponent
similar to shouldComponentUpdate
with the shallow comparison of props, state
Similar to PureComponent
in class component, we can use React.memo
in functional component as follows:
1 2 3 4 5 6 |
<span class="token keyword">function</span> <span class="token function">MyComponent</span> <span class="token punctuation">(</span> <span class="token parameter">props</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">/* render using props */</span> <span class="token punctuation">}</span> <span class="token keyword">export</span> <span class="token keyword">default</span> React <span class="token punctuation">.</span> <span class="token function">memo</span> <span class="token punctuation">(</span> MyComponent <span class="token punctuation">)</span> <span class="token punctuation">;</span> |
Using useMemo, useCallback hooks in a functional component
If the app has data that needs complex computation, we need to cached (memorized) these data so that we don’t have to recalculate if the input doesn’t change.
useMemo
1 2 |
<span class="token keyword">const</span> memoizedValue <span class="token operator">=</span> <span class="token function">useMemo</span> <span class="token punctuation">(</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">computeExpensiveValue</span> <span class="token punctuation">(</span> a <span class="token punctuation">,</span> b <span class="token punctuation">)</span> <span class="token punctuation">,</span> <span class="token punctuation">[</span> a <span class="token punctuation">,</span> b <span class="token punctuation">]</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> |
useMemo
only perform computeExpensiveValue
if a
or b
changes.
We can also apply useMemo
to cached a react component like this:
1 2 |
<span class="token keyword">const</span> memoizedGreeting <span class="token operator">=</span> <span class="token function">useMemo</span> <span class="token punctuation">(</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token operator"><</span> div <span class="token operator">></span> Hello <span class="token punctuation">{</span> name <span class="token punctuation">}</span> <span class="token operator">!</span> <span class="token operator"><</span> <span class="token operator">/</span> div <span class="token operator">></span> <span class="token punctuation">,</span> <span class="token punctuation">[</span> name <span class="token punctuation">]</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> |
useCallback
useMemo
is used to cached value, while useCallback
used to cached a callback
function
So we can use useCallback
to cached a funtion callback
doesn’t change reference in every render.
1 2 3 4 5 6 7 |
<span class="token keyword">const</span> memoizedCallback <span class="token operator">=</span> <span class="token function">useCallback</span> <span class="token punctuation">(</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token function">doSomething</span> <span class="token punctuation">(</span> a <span class="token punctuation">,</span> b <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> a <span class="token punctuation">,</span> b <span class="token punctuation">]</span> <span class="token punctuation">,</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> |
Virtualize Long Lists
This is a performance optimization technique if rendering a long, complex data list. This technique only renders a group of items in the list on the UI rather than rendering the entire list data
There are many libs supporting this technique, typically react-window and react-virtualized , which provide components for displaying list, grid, table.
Use a Production Build
When we release a react app we need to build in production
mode, this ensures the react version gets rid of unnecessary warnings, debug code, components, tools support while dev, and reduces build size, etc.
Use the build file:
1 2 3 |
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span> script</span> <span class="token attr-name">src</span> <span class="token attr-value"><span class="token punctuation">=</span> <span class="token punctuation">"</span> https://unpkg.com/ <a class="__cf_email__" href="/cdn-cgi/l/email-protection">[email protected]</a> /umd/react.production.min.js <span class="token punctuation">"</span></span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> script</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> script</span> <span class="token attr-name">src</span> <span class="token attr-value"><span class="token punctuation">=</span> <span class="token punctuation">"</span> https://unpkg.com/ <a class="__cf_email__" href="/cdn-cgi/l/email-protection">[email protected]</a> /umd/react-dom.production.min.js <span class="token punctuation">"</span></span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> script</span> <span class="token punctuation">></span></span> |
webpack:
1 2 3 4 5 6 7 8 9 |
<span class="token keyword">const</span> TerserPlugin <span class="token operator">=</span> <span class="token function">require</span> <span class="token punctuation">(</span> <span class="token string">'terser-webpack-plugin'</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> module <span class="token punctuation">.</span> exports <span class="token operator">=</span> <span class="token punctuation">{</span> mode <span class="token operator">:</span> <span class="token string">'production'</span> <span class="token punctuation">,</span> <span class="token comment">// important</span> optimization <span class="token operator">:</span> <span class="token punctuation">{</span> minimizer <span class="token operator">:</span> <span class="token punctuation">[</span> <span class="token keyword">new</span> <span class="token class-name">TerserPlugin</span> <span class="token punctuation">(</span> <span class="token punctuation">{</span> <span class="token comment">/* additional options here */</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> <span class="token punctuation">,</span> <span class="token punctuation">}</span> <span class="token punctuation">;</span> |
Conclude
Above are some points to note to improve the performance of the react app, some more techniques will be in the next part, please read it, thank you!