Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 69cc1ce

Browse files
committed
Tweaks on Advanced Performance
1 parent e29766a commit 69cc1ce

File tree

1 file changed

+21
-21
lines changed

1 file changed

+21
-21
lines changed

docs/docs/11-advanced-performance.md

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ One of the first questions people ask when considering React for a project is wh
99

1010
## Avoiding reconciling the DOM
1111

12-
React makes use of a *virtual DOM*, which is a descriptor of a DOM subtree rendered in the browser. This parallel representation allows React to avoid creating DOM nodes and accessing existing ones, which is slower than operations on JavaScript objects. When a component's props or state change, React decides whether an actual DOM update is necessary by constructing a new virtual DOM and comparing it to the old one. Only in the case they are not equal, will [React reconcile](http://facebook.github.io/react/docs/reconciliation.html) the DOM, applying as few mutations as possible.
12+
React makes use of a *virtual DOM*, which is a descriptor of a DOM subtree rendered in the browser. This parallel representation allows React to avoid creating DOM nodes and accessing existing ones, which is slower than operations on JavaScript objects. When a component's props or state change, React decides whether an actual DOM update is necessary by constructing a new virtual DOM and comparing it to the old one. Only in the case they are not equal, will React [reconcile](http://facebook.github.io/react/docs/reconciliation.html) the DOM, applying as few mutations as possible.
1313

14-
On top of this, React provides a component lifecycle function, shouldComponentUpdate, which is triggered before the re-rendering process starts, giving the developer the ability to short circuit this process. The default implementation of this function returns true, leaving React to perform the update:
14+
On top of this, React provides a component lifecycle function, `shouldComponentUpdate`, which is triggered before the re-rendering process starts, giving the developer the ability to short circuit this process. The default implementation of this function returns `true`, leaving React to perform the update:
1515

1616
```javascript
1717
shouldComponentUpdate: function(nextProps, nextState) {
@@ -21,7 +21,7 @@ shouldComponentUpdate: function(nextProps, nextState) {
2121

2222
Keep in mind that React will invoke this function pretty often, so the implementation has to be fast.
2323

24-
Say you have a messaging application with several chat threads. Suppose only one of the threads has changed. If we implement shouldComponentUpdate on the ChatThread component, React can skip the rendering step for the other threads:
24+
Say you have a messaging application with several chat threads. Suppose only one of the threads has changed. If we implement `shouldComponentUpdate` on the `ChatThread` component, React can skip the rendering step for the other threads:
2525

2626
```javascript
2727
shouldComponentUpdate: function(nextProps, nextState) {
@@ -30,22 +30,22 @@ shouldComponentUpdate: function(nextProps, nextState) {
3030
}
3131
```
3232

33-
So, in summary, React avoids carrying out expensive DOM operations required to reconcile subtrees of the DOM by allowing the user to short circuit the process using shouldComponentUpdate, and, for those which should update, by comparing virtual DOMs.
33+
So, in summary, React avoids carrying out expensive DOM operations required to reconcile subtrees of the DOM by allowing the user to short circuit the process using `shouldComponentUpdate`, and, for those which should update, by comparing virtual DOMs.
3434

3535
## shouldComponentUpdate in action
3636

37-
Here's a subtree of components. For each one is indicated what shouldComponentUpdate returned and whether or not the virtual DOMs were equivalent. Finally, the circle's color indicates whether the component had to be reconciled or not.
37+
Here's a subtree of components. For each one is indicated what `shouldComponentUpdate` returned and whether or not the virtual DOMs were equivalent. Finally, the circle's color indicates whether the component had to be reconciled or not.
3838

3939
<figure><img src="/react/img/docs/should-component-update.png" /></figure>
4040

41-
In the example above, since shouldComponentUpdate returned false for the subtree rooted at C2, React had no need to generate the new virtual DOM, and therefore, it neither needed to reconcile the DOM. Note that React didn't even had to invoke shouldComponentUpdate on C4 and C5.
41+
In the example above, since `shouldComponentUpdate` returned `false` for the subtree rooted at C2, React had no need to generate the new virtual DOM, and therefore, it neither needed to reconcile the DOM. Note that React didn't even had to invoke `shouldComponentUpdate` on C4 and C5.
4242

43-
For C1 and C3 shouldComponentUpdate returned true, so React had to go down to the leaves and check them. For C6 it returned true; since the virtual DOMs weren't equivalent it had to reconcile the DOM.
43+
For C1 and C3 `shouldComponentUpdate` returned `true`, so React had to go down to the leaves and check them. For C6 it returned `true`; since the virtual DOMs weren't equivalent it had to reconcile the DOM.
4444
The last interesting case is C8. For this node React had to compute the virtual DOM, but since it was equal to the old one, it didn't have to reconcile it's DOM.
4545

46-
Note that React only had to do DOM mutations for C6, which was inevitable. For C8 it bailed out by comparing the virtual DOMs, and for C2's subtree and C7, it didn't even have to compute the virtual DOM as we bailed out on shouldComponentUpdate.
46+
Note that React only had to do DOM mutations for C6, which was inevitable. For C8 it bailed out by comparing the virtual DOMs, and for C2's subtree and C7, it didn't even have to compute the virtual DOM as we bailed out on `shouldComponentUpdate`.
4747

48-
So, how should we implement shouldComponentUpdate? Say that you have a component that just renders a string value:
48+
So, how should we implement `shouldComponentUpdate`? Say that you have a component that just renders a string value:
4949

5050
```javascript
5151
React.createClass({
@@ -59,7 +59,7 @@ React.createClass({
5959
});
6060
```
6161

62-
We could easily implement shouldComponentUpdate as follow:
62+
We could easily implement `shouldComponentUpdate` as follow:
6363

6464
```javascript
6565
shouldComponentUpdate: function(nextProps, nextState) {
@@ -69,7 +69,7 @@ shouldComponentUpdate: function(nextProps, nextState) {
6969

7070
So far so good, dealing with such simple props/state structures is easy. We could even generalize an implementation based on shallow equality and mix it into components. In fact, React already provides such implementation: [PureRenderMixin](http://facebook.github.io/react/docs/pure-render-mixin.html).
7171

72-
But what if your components' props or state are mutable data structures?. Say the prop the component receives, instead of being a string like 'bar', is a Javascript object that contains a string such as, { foo: 'bar' }:
72+
But what if your components' props or state are mutable data structures?. Say the prop the component receives, instead of being a string like `'bar'`, is a Javascript object that contains a string such as, `{ foo: 'bar' }`:
7373

7474
```javascript
7575
React.createClass({
@@ -83,7 +83,7 @@ React.createClass({
8383
});
8484
```
8585

86-
The implementation of shouldComponentUpdate we had before wouldn't always work as expected :
86+
The implementation of `shouldComponentUpdate` we had before wouldn't always work as expected:
8787

8888
```javascript
8989
// assume this.props.value is { foo: 'bar' }
@@ -92,7 +92,7 @@ The implementation of shouldComponentUpdate we had before wouldn't always work a
9292
this.props.value !== nextProps.value; // true
9393
```
9494

95-
The problem is shouldComponentUpdate will return true when the prop actually didn't change. To fix this we could come up with this alternative implementation:
95+
The problem is `shouldComponentUpdate` will return `true` when the prop actually didn't change. To fix this we could come up with this alternative implementation:
9696

9797
```javascript
9898
shouldComponentUpdate: function(nextProps, nextState) {
@@ -127,13 +127,13 @@ React.createClass({
127127

128128
The first time the inner component gets rendered it will have `{ foo: 'bar' }` as the value prop. If the user clicks on the anchor, the parent component's state will get updated to `{ value: { foo: 'barbar' } }`, triggering the re-rendering process of the inner component, which will receive `{ foo: 'barbar' }` as the new value for the prop.
129129

130-
The problem is that since the parent and inner components share a reference to the same object, when the object gets mutated on line 2 of the onClick function, the prop the inner component had will change. So, when the re-rendering process starts, and shouldComponentUpdate gets invoked, `this.props.value.foo` will be equal to `nextProps.value.foo`, because in fact, `this.props.value` references the same object as `nextProps.value`.
130+
The problem is that since the parent and inner components share a reference to the same object, when the object gets mutated on line 2 of the `onClick` function, the prop the inner component had will change. So, when the re-rendering process starts, and `shouldComponentUpdate` gets invoked, `this.props.value.foo` will be equal to `nextProps.value.foo`, because in fact, `this.props.value` references the same object as `nextProps.value`.
131131

132132
Consequently, since we'll miss the change on the prop and short circuit the re-rendering process, the UI won't get updated from `'bar'` to `'barbar'`.
133133

134134
## Immutable-js to the rescue
135135

136-
[Immutable-js](https://github.com/facebook/immutable-js) is a Javascript collections library written by Lee Byron, which Facebook recently open-sourced. It provides *immutable** persistent* collections via *structural sharing*. Lets see what these properties mean:
136+
[Immutable-js](https://github.com/facebook/immutable-js) is a Javascript collections library written by Lee Byron, which Facebook recently open-sourced. It provides *immutable persistent* collections via *structural sharing*. Lets see what these properties mean:
137137

138138
* *Immutable*: once created, a collection cannot be altered at another point in time.
139139
* *Persistent*: new collections can be created from a previous collection and a mutation such as set. The original collection is still valid after the new collection is created.
@@ -148,7 +148,7 @@ y.foo = "baz";
148148
x === y; // true
149149
```
150150

151-
Although y was edited, since it's a reference to the same object as x, this comparison returns true. However, this code could be written using immutable-js as follows:
151+
Although `y` was edited, since it's a reference to the same object as `x`, this comparison returns `true`. However, this code could be written using immutable-js as follows:
152152

153153
```javascript
154154
var SomeRecord = Immutable.Record({ foo: null });
@@ -157,17 +157,17 @@ var y = x.set('foo', 'baz');
157157
x === y; // false
158158
```
159159

160-
In this case, since a new reference is returned when mutating x, we can safely assume that x has changed.
160+
In this case, since a new reference is returned when mutating `x`, we can safely assume that `x` has changed.
161161

162162
Another possible way to track changes could be doing dirty checking by having a flag set by setters. A problem with this approach is that it forces you to use setters and, either write a lot of additional code, or somehow instrument your classes. Alternatively, you could deep copy the object just before the mutations and deep compare to determine whether there was a change or not. A problem with this approach is both deepCopy and deepCompare are expensive operations.
163163

164-
So, Immutable data structures provides you a cheap and less verbose way to track changes on objects, which is all we need to implement shouldComponentUpdate. Therefore, if we model props and state attributes using the abstractions provided by immutable-js we'll be able to use PureRenderMixin and get a nice boost in perf.
164+
So, Immutable data structures provides you a cheap and less verbose way to track changes on objects, which is all we need to implement `shouldComponentUpdate`. Therefore, if we model props and state attributes using the abstractions provided by immutable-js we'll be able to use `PureRenderMixin` and get a nice boost in perf.
165165

166166
## Immutable-js and Flux
167167

168168
If you're using [Flux](http://facebook.github.io/flux/), you should start writing your stores using immutable-js. Take a look at the [full API](http://facebook.github.io/immutable-js/docs/#/).
169169

170-
Let's see one possible way to model the thread example using Immutable data structures. First, we need to define a Record for each of the entities we're trying to model. Records are just immutable containers that hold values for a specific set of fields:
170+
Let's see one possible way to model the thread example using Immutable data structures. First, we need to define a `Record` for each of the entities we're trying to model. Records are just immutable containers that hold values for a specific set of fields:
171171

172172
```javascript
173173
var User = Immutable.Record({
@@ -183,7 +183,7 @@ var Message = Immutable.Record({
183183
});
184184
```
185185

186-
The object the Record function receives defines the fields the object has and their default values.
186+
The object the `Record` function receives defines the fields the object has and their default values.
187187

188188
The messages *store* could keep track of the users and messages using two lists:
189189

@@ -204,4 +204,4 @@ this.messages = this.messages.push(new Message({
204204
205205
Note that since the data structures are immutable, we need to assign the result of the push function to this.messages.
206206
207-
On the React side, if we also use immutable-js data structures to hold the components' state, we could mix PureRenderMixin into all our components and short circuit the re-rendering process.
207+
On the React side, if we also use immutable-js data structures to hold the components' state, we could mix `PureRenderMixin` into all our components and short circuit the re-rendering process.

0 commit comments

Comments
 (0)