4
头图

The front-end development so far, why do both Vue and React need virtual DOM. Answer: DOM manipulation is slow, and JS can be fast , but is it really so?

From scratch: what is virtual DOM

Virtual DOM is essentially a mapping between js and DOM, which mentally represents a js object that can describe the DOM structure and its attribute information. In react, js objects behave as follows:

虚拟DOM

As far as this example is concerned, the virtual DOM should have the following two characteristics:

  • Virtual DOM is js object
  • A virtual DOM is a description of the real DOM

The past and present of virtual DOM

To learn a new knowledge point, not only to understand what this thing is, I think the more important thing should be what problem this thing solves. Any new technology will be a source without water and a tree without roots. After I understand the scene, I think it will be a natural thing to talk about realization.

The same goes for learning about the virtual DOM. To have a good study of virtual DOM, I think you should have a general understanding of front-end development.

Please pay attention to my official account, from zero handwriting a simplified version of Vue2/Vue3, zero handwriting Promise complete source code, using typescript hand-made wheels to encapsulate axios from zero, and teach you how to build node+egg projects and other high-quality resources. Follow the official account and send "1024" to get it! ! !
  1. DOM manipulation under native js

A long time ago, when the page was only used for simple display, the DOM operations used were not very frequent. At that time, it was still a table layout, and the pagers would spend a lot of time to realize the static layout of the page, such as the display page in the form of html+css, and finally add a small amount of js to achieve some interactions similar to hidden and displayed tabs. .

At this stage, the web page boys are also called cut-figure boys. We didn't need a lot of DOM manipulation, and we didn't have a lot of web pages without even business logic. At that time, we were still very happy. For such web pages, native js is enough.

  1. Liberate Compatible jQuery Period

With the development of the times, product managers are increasingly dissatisfied with these simple, boring, and rigid interactions, so they begin to pursue rich user experiences. Mapping into the implementation comes with a lot of DOM manipulation. In actual development, web pagers gradually discovered that the DOM manipulation API provided by native js is too TM difficult to use. So some Daniel developed a jQuery library to solve the problem that js is not easy to manipulate DOM, and by the way, it is compatible with the IE series that makes people want to run away at the mention of it, which is really exciting. jQuery's series of chained operations and assembleable plug-in extensions are really full of praise.

jQuery's DOM operation is simple and fast, so that the web pages are less swearing. It's still comfortable to read now. Being able to unify the rivers and lakes back then was truly well-deserved.

Although this helps people to operate the DOM in a more comfortable position, people gradually find that operating the DOM because of frequent data changes is also a big problem, which really breaks the hearts of web pagers.

  1. Early Template Solutions

jQuery is like a construction worker who can be used at will. If you want to renovate the building, you have to tell him to get the tools first, and then how to find the wall, then lift him up and build it up with cement bricks, and add the surface. ......

This kind of operation is really tiring. If there is a foreman in charge of things, I just tell him what I want to transform the wall into, and it is much more convenient for him to supervise the later things.

The template engine is the prototype of the foreman. Let's look at such an example. For example, now I have a class roster with the following data:

 const students = [
  { name: '小明', stu_no: '001' },
  { name: '刚子', stu_no: '002' },
  { name: '李华', stu_no: '003' }
]

The front end should be displayed in a list. We use the syntax of ejs here:

 <ul>
  <% students.forEach(student => { %>
    <li>
      <p>
        <label>姓名:</label>
        <span><%= student.name %></span>
      </p>
      <p>
        <label>学号:</label>
        <span><%= student.stu_no %></span>
      </p>
    </li>
  <% }) %>
</ul>

then insert the html into the document document

 const targetContainer = document.getElementById('target')
const innerHTML = ejs.render({students: students})

targetContainer.innerHTML = innerHTML

It's cool to use templates to write projects, just pay attention to the changes in the data layer. When the data changes, we do the render again. So far, the template engine has the prototype of the data rendering page. But it also has its corresponding shortcomings, such as:

  • always re-renders
  • When the amount of data is huge, the performance is not satisfactory
  • The actual application scenario is basically limited to "string concatenation"
  • And it is rigid, and the data needs to be re-spliced artificially when the data changes.
  • ......

Even so, the template engine is off to a good start, taking a new level of thought - spending a lot of energy on data rather than rendering views. So the core problem lies in performance. Every time the data changes, the entire list view has to be re-rendered drastically. Who can resist this?

  1. The advent of the virtual DOM

As a result, a group of people with lofty ideals (the following content is purely made up) proposed that since the template engine has to re-render every time, I will not re-render, but only re-render those DOMs that have changed. Since the performance loss of operating the real DOM Huge, then I can fake it. Thus, the virtual DOM turned out. Then let's compare the rendering process of template engine and virtual DOM during initial rendering:

  • The rendering of the template engine is: data + template --> directly rendered as real DOM --> mounted to the page
  • When rendering virtual DOM: data + template --> virtual DOM --> real DOM --> mount to page

The template in the virtual DOM should have its own special class template, like jsx in React is not a template in essence, but a js syntax sugar that is visually similar to a template.

It can be seen from the above comparison that the rendering of the virtual DOM has more virtual DOM layers. The benefit of this cache layer is that when there is a small amount of updates to the DOM, a diff operation is performed when re-rendering, to locate the part that needs to be modified and generate a patch set, and then make a patch.

The emergence of virtual DOM, is it really because of performance?

The development of the story seems to be for performance reasons, and the main contradiction in the development of the template engine to the virtual DOM seems to all point to performance. But did React really introduce virtual DOM in the first place because of performance? Let's compare the performance of template engine and virtual DOM in different scenarios. We must compare them in different scenarios. Talking about technology aside from scenarios is a hooligan.

In the process, the template engine and the first half of the virtual DOM search belong to the js category. For example, the template engine generates html strings, the virtual DOM rendering part of the virtual DOM rendering, and the diff in the two updated virtual DOMs are all in js. This does not involve the operation of the real DOM. In comparison, the performance loss of string splicing is obviously insignificant, and the traversal and recursive relative strings involved in diff Splicing is also time-consuming, so in the scope of js, the template engine will definitely win.

But in the operation of the real DOM in the last step, the two are indeed contrasted. At this time, it is really necessary to compare the scenes:

If the amount of data is huge, and there are tens of thousands of lists rendered on the page, but only one or two data needs to be changed, the template engine will not be as good as the diff patch of the virtual DOM even if the header is broken. However, if the data content changes very much, such that the differential update is very close to the full update, or it is already a full update, then the traversal and recursion of tens of thousands of pieces are enough for the client's diff to drink a pot.

So in these two extreme cases, each has its own merits. In fact, it is very much like life, always making a choice between the two. In different scenarios, the two are indistinguishable. But it always has to be divided into high and low. In actual development, whether in Vue or React, I think most of the changes are vm.xxx = xxx or this.setState({xxx: xxx}) , just A very few attributes have changed, even if xxx is an array, it is a process of reassignment.

Having said that, all the emerging evidence seems to point to performance improvements, even if we make trade-offs after the analysis, it is only in the scope of performance considerations. However, what I want to say is that what I said before is actually nonsense, what I want to say is actually: the value of virtual DOM is not only in performance .

Know the true face of Mount Lu

What I think of as virtual DOM, you may not agree. Just like seeing a beautiful woman, because of differences in aesthetics, everyone may not agree that she is a beautiful woman. What I'm giving may not be a standard answer. I think virtual DOM solves several crucial problems:

  1. Page performance improvement: Although the virtual DOM is not the optimal solution under the comparison of our previous arguments, in most scenarios, the virtual DOM can give your page a decent performance and provide you with a cooler development mode .
  2. Improvement of development efficiency: From the description of the front-end development history, it can be seen that every innovation in DOM operation is behind the improvement of development efficiency. It has to be mentioned that in the era of React or Vue, our development efficiency has improved a lot for the same page. As far as the development of the mvvm mode that outputs the content of the input box to the page, it can be quickly done by introducing Vue or React.
  3. Cross-platform problem: The virtual DOM is an abstract description of the rendered content, which makes the view layer and rendering layer decoupled. The description of the rendering layer in this layer can be multi-end, such as web, native, applet, etc. It may only need one piece of code to work on different ends. After all, even Vue3 also puts the content of DOM operation in a separate runtime-dom.js module, the purpose is to operate the content of the rendering layer at multiple ends to realize the possibility of cross-platform.

Summarize

This time, we first reviewed the development history of front-end operation DOM, from which we learned about the positioning and problems of virtual DOM, and then compared the rendering differences and performance differences between virtual DOM and template engine. Finally, the conclusion of the reason for the emergence of virtual DOM is made.

In addition: If there are any inappropriate expressions or knowledge points in the text, please leave a message for criticism and correction, and make progress together!


web瑞驰
46 声望3 粉丝

一枚自学前端的螺丝机