This is the 20th day of my participation in the August Text Challenge.More challenges in August

Mountaineering is full of feelings in the mountains, the view of the sea is overflowing in the sea — Liu Xie

preface

This article will teach you to understand the basic Virtual DOM algorithm, and try to explain the algorithm ideas of Virtual DOM clearly. Hopefully, this article will help you understand the Virtual DOM and give you some new ideas for programming your existing front end.

DOM manipulation evolution

In the early period

In the early days of the front-end industry, JavaScript was not the main character in the front-end world for a long time. People only used JS to do simple dynamic effects like drag and drop and hide. The DOM manipulation that front-end engineers need to worry about is limited in this period. Using JS and jQuery to modify the DOM at a specific point doesn’t seem too daunting.

Template period

With the continuous improvement of front-end business complexity, front-end page has higher and higher requirements for interactive experience, and the sudden increase of dynamic content brings a large number of DOM modification requirements. If engineers were required to modify DOM nodes one by one, the work would be desperate. The “template” solution was created

For example, if I have a student information table to display, I can give it a set of initialization data.

[{name: 'tes1'.age: 24
    },
    {
        name'Lili'.age22
    },
    {
        name: 'John'.age: 23}]Copy the code

Insert this set of data into the template:

<table>
    {% students.forEach(function(student){ %}
    <tr>
        <td>{% student.name %}</td>
        <td>{% student.age %}</td>
    </tr>
    {% }); %}
</table>
Copy the code

What does a template do for us? It’s going to read in your students data source, stuff it into the template code above, blend it together, and spit out a target HTML to you. This HTML code can then be rendered directly to the page as DOM.

The process goes something like this:

// Data and templates merge into HTML code
var targetDOM = template({data: students})
// Add it to the page
document.body.appendChild(targetDOM)
Copy the code

Problems with templates

The DOM scheme, in the form of a template, is actually very crude and contains quite a few pitfalls.

 

Now consider a common scenario: If I discover that one of the students in the table above has a wrong name — TES1 is actually called test. Now I’m going to change that name, so I’m going to change the name information in the students, what does the template do?

First, the template engine unlogs the entire targetDOM node. Then, go through the rendering process again:

Data + template =HTML code

2. Render the HTML code onto the page to form a real DOM

Originally I just wanted to change the name of TES1, now the whole table needs to be re-rendered. The scope of DOM manipulation extends from a small table field bit to an entire table. It doesn’t make sense.

The virtual DOM is the cornerstone of modern front-end frameworks

The following template implements DOM manipulation:

Logout of the old DOM -> data + template => a new set of HTML code -> mount the new DOMCopy the code

Both “old DOM” and “new DOM” refer to the overall update of the entire DOM corresponding to the template. What we did wrong was update the whole thing every time — if only there was a way to keep the data-driven idea of the template solution in place, while still being able to make small changes to the DOM at a specific point, like human-powered JS or jQuery.

What does it take for DOM manipulation to go from “one size fits all” to “refined”? Diff is needed!

Virtual DOM + DIff, a new DOM manipulation solution comes into being!

Among them, the virtual DOM layer is implemented with JS. In other words, at this stage all changes and comparisons are purely JS level calculations. JS vs DOM operations have a completely different level of performance cost. In this way, Virtual DOM perfectly solves the performance problems caused by template rendering.

The Diff algorithm

The react Diff algorithm

The React team didn’t use a recursive algorithm to compare two trees one by one. They adopted an algorithm of O(n) complexity — 100 nodes at a time now require 100 comparisons, which is a breeze for the browser. In fact, this algorithm is one of the highlights of React. Let’s take a look at how the O(n) algorithm is implemented:

The React team made the following assumptions based on the characteristics of the front-end interface:

The same component has the same DOM structure, and different components have different DOM structures

A group of child nodes at the same level that can be distinguished by a unique ID

In DOM structures, node operations across hierarchies are minimal and negligible

First, when we consider the “differences” of two trees, we can think layer by layer, or “layer by layer” (the relationship shown below).

When comparing two trees, the diff algorithm will compare the root nodes of the two trees first. If they are of different types, such as div, now P: then the two trees are considered completely different, they are two completely different components, so there is no need to compare the child nodes further down.

React will assume “You are still the same component” if the root node type is the same. Next, keep the component intact, check for changes in its properties, and update the component as the properties change.

React then jumps to the next level to compare the children of the root node:

React: There is no need to compare the child nodes of A and B. There is no need to compare the children of A and B. So you start with node A directly, delete it and its children and reconstruct it into B and its children.

Array dynamically generated components, why must have“Key”

Combining our previous diff analysis, let’s look at two Virtual DOM trees like this:

We compare the process of the second layer node:

  • Compare B to B, no change, no change
  • D and C are of different node types. Delete D and create C again
  • Delete E and create D again
  • Compare empty and E, E is new, E is new

D and E components are existing sub-components. How can we reuse existing components? We put a mark on it. This is key

We give each node a Key

Tips: Make sure the key is uniquely stable.