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