Turn from: 1190000006100489
React: A JavaScript library for building the user interface.
React only focuses on the UI layer; It uses virtual DOM technology to ensure high-speed rendering of its UI; it uses one-way data streams, so its data binding is simpler; how does it keep the UI rendering simple and efficient inside?
React does not directly manipulate the DOM, it maintains a fast-responding Dom description in memory, the Render method returns a description of the DOM, react can calculate the differences of two DOM descriptions, and then update the DOM in the browser.
This means that when react receives a props or state update, react updates the UI in the previous way. Even if it is reusedReactDOM.render(<Component />, mountNode), it is only used as a props update, not as a reload of the entire component. So react the entire UI rendering is relatively fast.
But there are a couple of questions here.
1. If the update props is the same as the old one, it is obvious that the UI will not change, but the react still has to perform a diff of the virtual DOM, which is a redundant performance loss, and the whole diff takes a long time when the DOM structure is more complex.
2. Since react always wants to make a diff of the virtual DOM, what is its diff rule? How to use it?
Purerendermixin
REACT provides us with purerendermixin for the first question. If the react component is purely functional, the same UI is presented for the same props and state components as the component, and this minxin can be used to optimize the performance of the react component.
var PureRenderMixin = require (‘react-addons-pure-render-mixin’);
React.createClass ({
mixins: [PureRenderMixin],
render: function () {
return <div className = {this.props.className}> foo </ div>;
}
});
The usage in ES6 is
import PureRenderMixin from ‘react-addons-pure-render-mixin’;
class FooComponent extends React.Component {
constructor (props) {
super (props);
this.shouldComponentUpdate = PureRenderMixin.shouldComponentUpdate.bind (this);
}
render () {
return <div className = {this.props.className}> foo </ div>;
}
}
The principle of PureRenderMixin is that it implements shouldComponentUpdate. In shouldComponentUpdate, it compares the current props and state with the next props and state. When the two are equal, it returns false, so that the component will not diff the virtual DOM.
Note here:
PureRenderMixin is only a shallow comparison. If the object contains a complex data structure, deep differences may produce misjudgments. Only used for components with simple props and state.
shouldComponentUpdate
Although React provides a simple PureRenderMixin to improve performance, but what if there are more special needs? What if the component has complex props and state? At this time, you should use shouldComponentUpdate to perform more customized performance optimization.
boolean shouldComponentUpdate (object nextProps, object nextState) {
return nexprops.id! == this.props.id;
}
This method is called before the React component needs to be updated. If this method returns false, the component is not updated; if it returns true, the component is updated. Within this method, the nextProps and current props, nextState and current state comparison can determine whether the component is updated.
If the data structure of the comparison is more complicated and deeper, the comparison process will also consume a lot of performance, and may not be worth the gains.
At this time, immutable.js is about to debut, and it is also produced by fb. Some people say that this framework is no less important than React, but React is too bright. It can solve the performance loss of complex data during deepClone and comparison.
Note: shouldComponentUpdate will not be called when the rendering is initialized, but it will not be called when the forceUpdate method is used to force the update.
render
The focus of PureRenderMixin and shouldComponentUpdate is whether the UI needs to be updated, and render pays more attention to the diff rules of the virtual DOM. How to minimize the diff results and simplify the process is the focus of optimization within render.
React assumes when performing virtual DOM diff:
1. Two components with the same class will generate similar tree structures, and two components with different classes will generate different tree structures.
2. A unique logo can be provided for the element, which remains unchanged during different rendering processes.
DOM structure
renderA: <div />
renderB: <span />
=> [removeNode <div />], [insertNode <span />
DOM attributes
renderA: <div id = "before" />
renderB: <div id = "after" />
=> [replaceAttribute id "after"]
Insert before DOM
renderA: <div> <span> first </ span> </ div>
renderB: <div> <span> second </ span> <span> first </ span> </ div>
=> [replaceAttribute textContent ‘second’], [insertNode <span> first </ span>]
Insert the DOM before, there is a key
renderA: <div> <span key = "first"> first </ span> </ div>
renderB: <div> <span key = "second"> second </ span> <span key = "first"> first </ span> </ div>
=> [insertNode <span> second </ span>]
Because it depends on two pre-judgment conditions, if these two conditions are not met, the performance will be greatly reduced.
1. The diff algorithm will not attempt to match subtrees of different component classes. If you find that the DOM structures output by the two component classes you are using are very similar, you can change these two component classes into one.
2. If a stable key is not provided (for example, generated by Math.random ()), all subtrees will be re-rendered at each data update.
to sum up
Use PureRenderMixin and shouldComponentUpdate to avoid unnecessary virtual DOM diff, optimize the diff speed of virtual DOM inside render, and minimize diff results.
Use immutable.js to solve complex data diff, clone and other problems.
React component performance optimization