These four tips are lessons I learned recently. Just want to share in case you find it useful.
When a component is only rendered in some condition, you can either do conditional rendering
https://gist.github.com/cf100928c4bc0f753fb6d334ee486820
Or use class name /css to toggle hiding of the component
https://gist.github.com/83739f48cff305f9df4959cf872b36c9
Usually we should use conditional rendering. It is faster because no component is generated and thus React does not need to do rendering / reconcilation / DOM operation. In contrast, in the css approach, React still needs to create the DOM and do all the updating even though it’s never shown.
Another benefit of conditional rendering is dynamic code splitting. If we enable code splitting by component, the component chunk file will only be downloaded when the condition is true in the conditional rendering. When the condition is false, the component function is not executed, and thus the chunk containing the component will not be requested. This is especially useful for components that only show in edge cases (e.g. error dialog). Most users won’t see these components, and thus don’t need to download these scripts.
One case that we probably want to go with css approach is when the component will be toggled frequently. Using css to hide and show the DOM will be cheaper than adding and removing the DOM on a frequent basis.
ES6 provides a convenient way to destruct object, and react supports this syntax as well. You can do
https://gist.github.com/1d20b326f4e21f96ee6b31b6c42f54a3
to pass all fields in props
to a component. The benefit is that this saves code, especially you have a long list of props for the component. But I’d say the harm outweighs the benefit. Prop spreading makes it difficult to identify what props are exactly passed and what props are really needed for the component. When refactoring, it’s difficult to tell whether it’s safe to remove a prop. For example,
https://gist.github.com/46ad6f4fdfab449bbd33931b0f1336ff
In the Profile
component, prop gender
seems not to be used anywhere. With a command F search but it is actually implicitly passed to Detail
. During refactoring, it is likely that one will remove gender
from the connected profile component, which will cause Detail
to err.
Did you ever write a component like this?
https://gist.github.com/2bfecea42c2649b4eeea4658d1d2ec68
Since each time a new function instance is created in the click handler, the InnerComponent
always receives a new prop value, so it always re-renders. Instead, they suggest declaring the function separately and referring to the function in the click handler. Because it is the same function reference, the component won’t re-render.
https://gist.github.com/d084dcf15f6ab4f631fb92f116441af0
But that’s actually not true. Avoiding the inline function is only half of the story. Whether InnerComponent
will re-render also depends on how it is implemented. If InnerComponent
is a functional component or a regular class component, it will always re-render, regardless of prop change.
https://gist.github.com/537a7e88c132a8daf00b7601331d4d66
Only when InnerComponent
implements shouldComponentUpdate
or when it extends from PureComponent
will it compare prop changes. In other cases (functional component and regular class component), it will always re-render regardless of prop changes.
So is this bad? Shall we always use PureComponent
or implement shouldComponentUpdate
?
First, re-rendering is not bad at all. In fact, re-rendering is pretty cheap. All it does is to create a virtual DOM tree in memory, but it does not touch the real DOM, which is why it is fast. After the virtual DOM is created, it compares with the existing one. This process is called /reconciliation/, which is not expensive either. If it decides that DOM needs to be updated, react will /commit/ the change and manipulate real DOM, and that is what could drag down performance. Therefore, we don’t really need to worry about re-rendering most of time; just let react decide whether to update DOM or not.
Second, PureComponent
or shouldComponentUpdate
can actually harm performance. Most of time our components do need to update. In those cases, the extra prop comparisons only adds additional computing /on top of/ re-rendering. Read @Ryan’s React, Inline Functions, and Performance – componentDidBlog to learn his story.
Third, PureComponent
or shouldComponentUpdate
could lead to unexpected behavior. Imagine you have a pure component as a parent component. When it decides not to re-render (because no prop changes), its child components will not change either. It may result in UI failing to update with user interaction. That’s one reason why pure components are not the default behavior.
In summary, because re-rendering does not necessarily hit performance (and most often doesn’t) and also because of the potential risk of pure component, it is not a good practice to pre-optimize components. Only do it when you do notice a performance issue.
These are the four lessons I learned for React recently, somewhat random, but hopefully useful! To reiterate:
Tip #1, Use conditional rendering because it is usually faster and good for lazy loading Tip #2, Restrain from prop spreading because it is bad for readability and refactoring Tip #3, Decompose into smaller components if you have a sub render method because it makes component easier to read and test Tip #4, Don’t pre-optimize component performance because React is usually fast enough!