Before we talk about the Virtual DOM, we can first understand what the real DOM is
Virtual DOM
A Virtual DOM is essentially a JavaScript object that represents the real DOM. That is, THE DOM structure of THE JS object simulation, the comparison of DOM changes in the JS layer to do. Make the UI render look like UI = f(data). Example: a piece of tag text in HTML
<ul id="list">
<li class="item">Item1</li>
<li class="item">Item2</li>
</ul>
Copy the code
Virtual DOM structure can be expressed as:
{
tag: "ul".attrs: {
id: "list"
},
children: [{tag: "li".attrs: { className: "item" },
children: ["Item1"] {},tag: "li".attrs: { className: "item" },
children: ["Item2"]]}}Copy the code
Tag is the name of the tag attrs is an object made up of attributes of the tag children are children contained within the tag
React creates a Virtual DOM by using the name, properties, and content of JSX elements as objects and their properties.
Why the Virtual DOM
- Cross-platform. Support cross-platform, can render JS objects to the browser DOM outside the environment, through the Virtual DOM can achieve server-side rendering. For example, there is no DOM in Node.js, you can use Virtual DOM to achieve SSR. Cross-platform development is supported, such as ReactNative.
- Performance optimization. One secret of front-end performance optimization is to operate DOM as little as possible. The excellent Virtual DOM Diff algorithm enables Virtual DOM to place DOM comparison operations in THE JS layer, and to update the differences into DOM as much as possible at one time during the patch process to reduce unnecessary redrawing of the browser. Improve efficiency. This ensures that the DOM does not suffer from poor performance.
- Development experience. We update the web display by manipulating HTML elements, first fetching them and then updating them. Although there is a jQuery framework to implement it, it is still quite complex. The React framework uses the Virtual DOM to help developers avoid complex apis, write UI declaratively and focus on changing data.
However, for performance optimization of a single scenario, it is more suitable to optimize js specifically for that scenario than the Virtual DOM scheme.
React Virtual DOM
Virtual DOM elements
In React development, Virtual DOM elements are React elements, and React elements are often written using JSX, such as simple ones
<div>Hello</div>
Copy the code
A little bit more complicated
<div className="divStyleName" onClick={(e) => console.log()}> Hello <img SRC ="pic_url">img</img> <div>div2</div> <div></div> </div>;Copy the code
However, using JSX in React is not mandatory. Because the JSX element just calls react. createElement(Component, props,… Children) grammatical sugar. The essence is JavaScript, and all JSX syntax will eventually be translated into calls to this method. So anything you can do with JSX can be done with pure JavaScript. At the same time, the browser cannot read JSX directly, and in order for the browser to read JSX, you need to configure the JSX compilation in the project build environment. For example, JSX converters like Babel convert JSX statements into target JS code and pass it to the browser so that the JS engine can execute the statement successfully.
Write the following JSX example in pure JavaScript (translated by Babel)
React.createElement("div", {
className: "divStyleName".onClick: e= > console.log('Clicked')},"Hello", React.createElement("img", {
src: "pic_url"
}, "img"), React.createElement("div".null."div2"), React.createElement("div".null));
Copy the code
The react. createElement analysis starts with the first parameter value being the component name. The second parameter value is an object made up of the component properties. The third and last parameter values are child elements. If the child element is still a JSX element, the React. CreateElement is used to create the object. The React element created by createElement is the element of the virtual DOM tree, thus forming a virtual DOM tree.
Take a look at the results of the above in a browser window
Then customize a component called HelloComponent, which JSX implements as
class HelloComponent extends React.Component {
render() {
return <div>Hello {this.props.toWhat}</div>;
}
}
<HelloComponent toWhat="World" />
Copy the code
The corresponding JS code after Babel translation is
class HelloComponent extends React.Component {
render() {
return React.createElement("div".null."Hello ".this.props.toWhat);
}
}
React.createElement(HelloComponent, {
toWhat: "World"
});
Copy the code
Then look in your browser window
Note that the value of type is a class constructor
This is the first letter of a component in JSX that Babel determines at compile time:
- When the first letter is lowercase, it is treated as a native HTML tag of the same name, and the first variable of createElement is compiled as a string
- When the first letter is capitalized, it is considered a custom component, and the first variable of createElement is compiled as an object.
Therefore, the custom component name must start with a capital letter.
CreateElement (Component, props,… How to build the Virtual DOM
Implementation principle of Virtual DOM
React source code
ReactElement
Since it’s react. createElement, it’s natural to go to the react. js file and look at its createElement method. The createElement method in ReactElement. Js returns a ReactElement object
/** * Create and return a new ReactElement of the given type. * See https://reactjs.org/docs/react-api.html#createelement */
export function createElement(type, config, children) {
let propName;
// Reserved names are extracted
const props = {};
let key = null;
let ref = null;
let self = null;
let source = null;
/ *... Ref, source, self, props, etc. * /
return ReactElement(
type,
key,
ref,
self,
source,
ReactCurrentOwner.current,
props,
);
}
Copy the code
Let’s look at the implementation of the ReactElement method
const ReactElement = function(type, key, ref, self, source, owner, props) {
const element = {
// This tag allows us to uniquely identify this as a React Element
?typeof: REACT_ELEMENT_TYPE,
// Built-in properties that belong on the element
type: type,
key: key,
ref: ref,
props: props,
// Record the component responsible for creating this element.
_owner: owner,
};
if (__DEV__) {
// The attributes of element are assigned
}
return element;
};
Copy the code
React returns a JS object called ReactElement:
{
? typeof: REACT_ELEMENT_TYPE,
type: type,
key: key,
ref: ref,
props: props,
_owner: owner,
}
Copy the code
The structure is exactly the structure of the react.createElement result seen above in the browser window.
This section describes the properties of the ReactElement object and their meanings.
-
? Typeof: The React element’s identity, i.e. “React. Element”, of type Symbol.
- Type: The type of the React element. As seen earlier, the value can be a string or a class constructor.
- Properties of the React element, which is an object consisting of JSX properties and child elements.
- Key: The React element key, which is used in the Virtual DOM Diff algorithm.
- Ref: The ref attribute of the React element. When the React element generates a real DOM element, it returns a reference to the DOM element.
- _owner: the component responsible for creating the React element.
Create a Virtual DOM tree
Once you know the individual ReactElement object, the example layer above calls react. createElement to create a Virtual DOM Tree that generates the native Virtual DOM object.
React.createElement("div", {
className: "divStyleName".onClick: e= > console.log('Clicked')},"Hello", React.createElement("img", {
src: "pic_url"
}, "img"), React.createElement("div".null."div2"), React.createElement("div".null));
Copy the code
The resources
See more examples of JSX conversion to JavaScript written in the online Babel editor
React Virtual DOM
The React source