Transferred from: Http://www.tuicool.com/articles/Ar6Zruq
React itself is very concerned about performance, the virtual DOM provided with the diff algorithm, to achieve the minimum granularity of DOM operation change is also very efficient. However, its component rendering mechanism also determines the finer optimizations that can be made when updating components.
React Component Rendering
React component rendering is divided into initialization rendering and update rendering.
The Render method of all components under the root component is called when the rendering is initialized, such as (green means rendered, this layer is no problem):
But when we want to update a subcomponent, such as the green component (which is passed down from the root component, the data applied to the green component changes):
Our ideal state is to invoke only the render of the component on the critical path, such as:
However, the default practice of react is to invoke the render of all components, and then compare the generated virtual DOM, and not update it if it is unchanged. This contrast between render and virtual Dom is obviously wasteful, such as (yellow represents wasted render vs. virtual DOM)
So how to avoid this waste problem, it is necessary to take ourshouldComponentUpdate
Shouldcomponentupdate
React calls a function when each component's lifecycle is updated shouldComponentUpdate(nextProps, nextState)
. Its duty is to return TRUE or false,true to indicate that it needs to be updated, false to indicate that it is not required, and return to True by default, even if you do not have the Shouldcomponentupdate function defined in the display. It is not difficult to explain the waste of resources that have occurred above.
To further illustrate the problem, we refer to a map of the official website to explain, such as (SCU indicates shouldcomponentupdate, green means return True (need to update), red means return false (do not need to update); Vdomeq represents virtual Dom alignment, Green is consistent (no update required), red indicates change (requires update)):
Depending on the rendering process, you will first determine whether the Shouldcomponentupdate (SCU) needs to be updated. If an update is required, the calling component's render generates a new virtual DOM, which is then compared to the old virtual Dom (VDOMEQ), if the comparison is not updated, and if the contrast is different, the DOM is updated according to the minimum granularity change, and if the SCU does not need to be updated, it is directly unchanged. At the same time its child elements remain unchanged.
C1 root node, green Scu (True), indicates that an update is required, and then vdomeq red, indicating that the virtual DOM is inconsistent and needs to be updated.
C2 node, red Scu (false), indicating that no updates are required, so c4,c5 are no longer checked
C3 node with C1, need to update
The C6 node, Green Scu (True), represents the need to update and then VDOMEQ red, which indicates that the virtual DOM is inconsistent and updates the DOM.
C7 node with C2
The C8 node, Green Scu (True), represents the need to update and then Vdomeq Green, which indicates that the virtual DOM is consistent and does not update the DOM.
To avoid a certain amount of waste, react officially added the stateless component in version 0.14, as follows:
Es5function HelloMessage (props) { return <div>hello {props.name}</div>;}
Es6const HelloMessage = (props) = <div>hello {props.name}</div>;
Refer to the official website: Reusable Components
Now that the key is understood, it is time to cut into our large and small package of components.
Kind, directly returning some components that do not need to be updated to False
Below we take the volume icon as an example, this is an SVG icon, do not need to update, so directly return false
Import React, {Component} from ' React '; class Mic extends Component { Constructor (props) { super (props); } shouldcomponentupdate () { return false; } Render () { return ( <svg classname= "icon-svg icon-mic" xmlns= "Http://www.w3.org/2000/svg" width= "32" height= "" viewbox= "0 0" aria-labelledby= "title" > <title>mic</title> <path Classname= "path1" d= "M15 22c2.761 0 5-2.239 5-5v-12c0-2.761-2.239-5-5-5s-5 2.239-5 5v12c0 2.761 2.239 5 5 5zm22 14v3c0 3.8 66-3.134 7-7 7s-7-3.134-7-7v-3h-2v3c0 4.632 3.5 8.447 8 8.944v4.056h-4v2h10v-2h-4v-4.056c4.5-0.497 8-4.312 8-8.944v-3h-2z "></path> </svg> ) }}export default Mic;
Presenting illegal weapons, compare data to determine if updates are required
First, an example of the official website, by determining whether the ID changes to determine whether the need for updates:
Shouldcomponentupdate:function (Nextprops, nextstate) { return nextprops.id!== this.props.id;}
Does not seem so iffy, direct a !==
comparison is OK, that is not all can be so direct comparison can it? Let's take a look at the respective comparisons of JS's two data types (primitive and reference types)
The original type var a = ' Hello the '; var b = a;b = B + ' world '; console.log (a = = B); false//reference type var c = [' Hello ', '];var d = c;d.push (' world '); Console.log (c = = = d); True
We can see A and B, but C and D are the same, which modifies D and modifies C directly, and how to compare (the difference between the original type and the reference type is not explained here).
Now it seems that we have dealt with the score, the raw type data and the reference type data have to be handled in different ways.
Raw type data
There's nothing to say, just the right. But everyone is want to lazy, this if each component to write down also very troublesome, so react official has a plugin to help us fix this matter:
Purerendermixin (ES5 plug-in)
var purerendermixin = require (' react-addons-pure-render-mixin '); React.createclass ({ mixins: [Purerendermixin], render:function () { return <div classname={ this.props.classname}>foo</div>; }});
Shallow Compare (ES6 plug-in)
var shallowcompare = require (' react-addons-shallow-compare '); Export class Samplecomponent extends React.component { shouldcomponentupdate (Nextprops, nextstate) { return Shallowcompare (this, nextprops, nextstate); } Render () { return <div classname={this.props.classname}>foo</div>;
Reference type Data
Since the reference type data always returns True, then you have to deal with it, can you turn the data before and after into a different reference, then it is not equal? So there's our immutable data.
React officially provided a immutability Helpers
Const NewValue = { ... oldValue //Make the changes you want here}; False//False
And then shouldComponentUpdate
do the comparison in the
Shouldcomponentupdate (nextprops) {
return isobjectequal (this.props, nextprops);}
Instead of judging the whole object, we are using the update data Object.assign({}, state, {newkey: newValue}
(data management using redux) in reducer, and then deciding whether to update the component based on a specific field, such as title or ID.
Shouldcomponentupdate:function (Nextprops, nextstate) { return nextprops.title!== this.props.title;}
Exploration and practice of React component performance optimization