Skip to content

Commit 6b503de

Browse files
committed
Pure component performance impact
1 parent 931ad9a commit 6b503de

File tree

3 files changed

+69
-9
lines changed

3 files changed

+69
-9
lines changed
+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
**Generally people think, an easy way to optimize a React component for performance is to make it a class, and make it extend React.PureComponent instead of React.Component. This way, the component will only re-render if it’s state is changed or if it’s props have changed. It will no longer mindlessly re-render every single time its parent re-renders; it will ONLY re-render if one of its props has changed since the last render.**
2+
3+
However its not as straightforward. Read this - [https://cdb.reacttraining.com/react-inline-functions-and-performance-bdff784f5578](https://cdb.reacttraining.com/react-inline-functions-and-performance-bdff784f5578) - Key takeaway from this article is - we dont have to user Pure component in all places, as it would NOT have any performance optimization effect generally. So, keep PureComponent on the shelf until you have a measurement to justify it.
4+
5+
You can see real performance improvements by understanding two things: shouldComponentUpdate and JavaScript strict equality comparisons.
6+
7+
1. So, if you inline an object in your JSX, it will fail the PureComponent prop diff and move on to diffing the more expensive React elements. The element diff will come up empty and now we’ve wasted time on both diffs. Since functions are objects and PureComponent does a strict equality check on props, an inline function will always fail the prop diff and move on to the element diff in the reconciler.
8+
2. If a component usually changes when there’s an update, then a PureComponent will be doing two diffs instead of just one (props and state in shouldComponentUpdate, and then the normal element diff).
9+
10+
Why - Think about it. If you have a Component how many diffs are there? If you have a PureComponent how many diffs are there? The answers are “just one” and “at least one and sometimes two”, respectively. If a component usually changes when there’s an update, then a PureComponent will be doing two diffs instead of just one (props and state in shouldComponentUpdate, and then the normal element diff). Which means it’s going to be slower usually but faster occasionally. Apparently, most of my components changed most of the time, so on the whole, my app got slower. Oops.
11+
12+
Oops - (Meaning after refactoring bunch of my regular component with Pure Component, the App actually got slower). So keep PureComponent on the shelf until you have a measurement to justify it.
13+
14+
#### Now some scenarios
15+
16+
#### 1-st Scenario
17+
18+
#### DOM component event handler
19+
20+
````js
21+
22+
<button
23+
onClick={() => this.setState(…)}
24+
>click
25+
</button>
26+
27+
```js
28+
29+
It’s common to do nothing more than setState inside of event handlers for buttons, inputs, and other DOM components. This often makes an inline function the cleanest approach. Instead of bouncing around the file to find the event handlers, they’re colocated. The React community generally welcomes colocation.
30+
31+
The button component (and every other DOM component) can’t even be a PureComponent, so there are no shouldComponentUpdate referential identity concerns here.
32+
33+
So, the only reason to think this is slow is if you think simply defining a function is a big enough expense to worry about. We’ve discussed that there is no evidence anywhere that it is. It’s simply armchair performance postulation. These are fine until proven otherwise.
34+
35+
36+
#### 2-nd Scenario - A “custom event” or “action”
37+
38+
```js
39+
<Sidebar
40+
onToggle={isOpen => {
41+
this.setState({ sidebarIsOpen: isOpen });
42+
}}
43+
/>
44+
````
45+
46+
If Sidebar is a PureComponent we will be breaking the prop diff. Again, since the handler is simple, the colocation can be preferable.
47+
With an event like onToggle, why is Sidebar even diffing it? There are only two reasons to include a prop in the shouldComponentUpdate diff:
48+
You use the prop to render.
49+
50+
You use the prop to perform a side-effect in componentWillReceiveProps, componentDidUpdate, or componentWillUpdate.
51+
Most on<whatever> props do not meet either of these requirements. Therefore, most PureComponent usages are over-diffing, forcing developers to maintain referential identity of the handler needlessly.
52+
53+
#### We should only diff the props that matter. That way people can colocate (inline function execution inside render / return) handlers and still get the performance gains you’re seeking (and since we’re concerned about performance, we’re diffing less!).
54+
55+
#### Conclusion
56+
57+
Pure Components gives a considerable increase in performance because it reduces the number of render operation in the application which is a huge win for complex UI and therefore advised to use if possible. Also, there will be cases where you want to use the lifecycle methods of Component and in such cases, we cannot use stateless components.
58+
59+
#### Reading
60+
61+
1. [https://cdb.reacttraining.com/react-inline-functions-and-performance-bdff784f5578](https://cdb.reacttraining.com/react-inline-functions-and-performance-bdff784f5578)

React/pureComponent.md

+1-6
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,6 @@ But a pure component, on the other hand, will not rerender if its parent rerende
1919

2020
Using PureComponent will help you prevent this wasted re-render. For instance, if a prop is a string or boolean and it changes, a PureComponent is going to recognize that, but if a property within an object is changing, a PureComponent is not going to trigger a re-render.
2121

22-
**An easy way to optimize a React component for performance is to make it a class, and make it extend React.PureComponent instead of React.Component. This way, the component will only re-render if it’s state is changed or if it’s props have changed. It will no longer mindlessly re-render every single time its parent re-renders; it will ONLY re-render if one of its props has changed since the last render.**
23-
2422
Here’s where immutability comes in: if you’re passing props into a PureComponent, you have to make sure that those props are updated in an immutable way. That means, if they’re objects or arrays, you’ve gotta replace the entire value with a new (modified) object or array. Kill it off and replace it with a clone.
2523

2624
**If you modify the internals of an object or array – by changing a property, or pushing a new item, or even modifying an item inside an array – then the object or array is referentially equal to its old self, and a PureComponent will not notice that it has changed, and will not re-render. Weird rendering bugs will ensue.**
@@ -75,10 +73,6 @@ Also in cases where you want to use lifecycle methods of Component then we have
7573

7674
Suppose you want to create a label with some beautiful UI which will be used to rate the credibility of a profile like BEGINNER, MODERATE, EXPERT. Since its a very small component whose re-render will hardly make any difference and creating a new component for such a small case will be time-consuming. Also if you keep making components for very small-small view, soon you will end up with so many components and it will be hard to manage when working with a big project. Also always keep in mind Pure Component comes with peculiarities of the shallowEqual.
7775

78-
#### Conclusion
79-
80-
Pure Components gives a considerable increase in performance because it reduces the number of render operation in the application which is a huge win for complex UI and therefore advised to use if possible. Also, there will be cases where you want to use the lifecycle methods of Component and in such cases, we cannot use stateless components.
81-
8276
Stateless Components are easy and fast to implement. They are good for very small UI view where re-render cost won’t matter that much. They provide cleaner code and less number of files to deal with.
8377

8478
### What is Shallow Comparison
@@ -105,3 +99,4 @@ In other words, shallow comparison will check that primitives have the same valu
10599
4. [https://logrocket.com/blog/pure-functional-components/](https://logrocket.com/blog/pure-functional-components/)
106100
5. [https://daveceddia.com/react-redux-immutability-guide/](https://daveceddia.com/react-redux-immutability-guide/)
107101
6. [https://reactjs.org/docs/react-api.html#reactpurecomponent](https://reactjs.org/docs/react-api.html#reactpurecomponent)
102+

React/this.props.children.md

+7-3
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ function App () {
3636
<Picture key={PIcture.id} src={picture.src} >
3737
// whatever is placed here is passed as props.children
3838
// Like I can place a <div></div> here and it will be rendered as a child to the Picture component.
39+
// Note, I am not including this extra divs in the Picture componet, but here in App component, where I am calling the picture component.
3940
</Picture>
4041
</div>
4142
)
@@ -50,11 +51,14 @@ You might want to assume that App.js will render as its html within the App.js,
5051

5152
Anything inside the <Picture> JSX tag in the App component gets passed into the Picutre component as a children.prop. Since Picture renders {props.children} inside a <div>, the passed elements appear in the final output.
5253

53-
This de-couples the <Picture> component from its content and makes it more reusable. So basically I take code out of <Picture> component and put them just-in-time, within <Picture> when this component itself is being called or rendered. See this example
54+
This de-couples the <Picture> component from its content and makes it more reusable, because I will put the children when the Picture component renders inside a parent component, and not when its defined.
55+
56+
So basically I take code out of <Picture> component and put them just-in-time, within <Picture> when this component itself is being called or rendered. See this example for a simple implementation.
57+
5458
[https://medium.com/javascript-in-plain-english/how-to-use-props-children-in-react-7d6ab5836c9d](https://medium.com/javascript-in-plain-english/how-to-use-props-children-in-react-7d6ab5836c9d)
5559

5660
#### Further Reading
5761

58-
### [Another simple example is here](https://codepen.io/rohanpaul/pen/bxoMxr)
62+
#### [Another simple example is here](https://codepen.io/rohanpaul/pen/bxoMxr)
5963

60-
### [https://codeburst.io/a-quick-intro-to-reacts-props-children-cb3d2fce4891](https://codeburst.io/a-quick-intro-to-reacts-props-children-cb3d2fce4891)
64+
#### [https://codeburst.io/a-quick-intro-to-reacts-props-children-cb3d2fce4891](https://codeburst.io/a-quick-intro-to-reacts-props-children-cb3d2fce4891)

0 commit comments

Comments
 (0)