Why Virtual DOM

introduction

As a front-end developer, no matter whether you have used Vuea framework as a technology stack or not, you should have heard of DOMthe concept of virtualization, also known as VDom.
Virtual DOM was first proposed by the facebook (now called Meta) technical team, and it was first used in the React framework, and then the concept of virtual DOM was introduced in Vue2.0.
The MVVM framework page rendering under the blessing of virtual DOM:
VDOM.jpg

Before entering VDom, let's first understand the JavaScript operation DOMmethod and performance difference;

The method and performance of JS manipulating DOM

JavaScriptThe operation DOMgenerally adopts the following two methods:

  • JavaScriptOperate directly through native code DOM;
  • Direct operation through html string splicing + innerHTML DOM;

native operation

When our front-end developers first contact JavaScript, we will learn how to use native js to DOMoperate (add, delete, modify, check, event binding, etc.).
For example, there is the following code:

<div id="testEle">这是div的文本内容</div>
// 修改div的内容
const ele = documont.querySelector('#testEle');
div.innerText = "使用js-innerText修改dom文本"
// or
div.textContent = "使用js-textContent修改dom文本"

innerHtml

Use the innerHTML method

const html = `<div>使用innerHTML</div>`
div.innerHtml = html;

Virtual DOM

Here first explain what is virtual DOM, in fact, virtual DOM is 一段用来描述真实的DOM的JavaScript代码(对象)并能根据一定的规则转换成真实的DOM节点.
Use virtual DOM to manipulate html

const virtualDOM = {
    
    
  tag: 'div',
  children: [{
    
     children: '使用虚拟DOM操作html' }]
}
// render 函数将虚拟 DOM 创建为真实 DOM ,并将其插入到文档中
render(virtualDOM)

The above are the three ways of operating DOM, which are somewhat different in writing. The following focuses on analyzing performance issues;

Performance difference comparison

First, there are two important points to declare:

  • The operation performance of js is far greater than that of dom, and the two of them are not in the same order of magnitude;
  • The method of natively operating dom in js should remove the innerHTML method, because innerHTML is more complicated;

fastest performance

The most direct way to modify dom is to use the native method, which is also the best performance choice;

div.textContent = "使用js-textContent修改dom文本"

Because we know which part of the dom structure needs to be modified and what content to modify, it is optimal to directly use js to operate dom

Performance of Virtual DOM

Using virtual DOM to operate DOM is actually to find out DOMthe difference before and after virtualization, and then update it, please see the following sample code:

<!-- 原始的dom代码如下 -->
<div>虚拟DOM修改前</div>
<!-- 修改后的dom代码 -->
<div>虚拟DOM修改后</div>

It needs to be said here that the virtual DOMbottom layer is still operated with native js DOM, but we have made a layer of encapsulation for the modification. So the performance of virtualization is lower than that of DOMnative js operation ; then why do we need to add an additional layer of encapsulation here? First of all, we need to know that the biggest front-end performance is the frequent operation of the DOM. Frequent changes to the DOM will cause the browser to reflow and return. Therefore, this layer of abstraction calculates the DOM difference as much as possible during the "frequent operation" process. The final result is to ensure that the DOM will not cause performance consumption due to excessive operations. For example, when ABCAD occurs during DOM changes, direct operation of AD in VDom greatly reduces the waste of intermediate processes. From the perspective of the framework, the abstraction of DOM operations in the middle layer can liberate developers from manual operations on the DOM. At the same time, it can get more platform support in adapting to more "middle layers" and realize the cross-platform underlying support of the framework.DOM

The conclusions we can draw from the above cases are:

  • Performance of native js operation DOM= performance of js operation DOM;
  • Virtual DOMperformance = the performance of js to find out DOMthe difference before and after + DOMthe performance of js operation;

According to the above formula, only when js找出DOM前后差异的性能the consumption is 0, the performance of the two will be equal, but it will never exceed 原生js操作DOM的性能, so when we use the algorithm in the framework to compare the virtual DOMdifference, it is an infinite optimization and its performance consumption Minimize (this is why diffthe algorithm is used later)
As for why virtual is still used DOM, this question will be discussed at the end of the article.

performance of innerHTML

innerHTMLIt is not a simple assignment. If the page wants to render the content of the html document, it must first parse innerHTMLthe content into DOMa structure tree, and then insert it into DOMthe document structure. Of course, the old document structure needs to be deleted before inserting. There are several key questions here:

  • parse DOMtree
  • delete the original DOMstructure
  • create new DOMstructure

The above three key points 解析DOM结构树belong to the calculation of the js level, and the other two belong to DOMthe operation calculation of the level.

Comparison of the three

Now conduct a comparative analysis of the performance consumption of the three:

Operation method JS level DOMlevel
Native JS Pure JS operation DOMoperation
innerHTML Pure JS operation html string DOMparsing DOMcreate
virtualDOM create virtualDOM DOMcreate

The above table compares the performance consumption of creating a new page, and first puts aside the native JS method (because this method has been mentioned above, it is optimal) and only compares the difference in performance loss between virtual and virtual DOM;innerHTML

  • innerHTMLPerformance loss = js operation html string splicing performance loss + DOMcreated performance loss;
  • Virtual DOMperformance loss = performance loss of js creating virtual DOMobjects + DOMperformance loss of creation;

Comparing from the dimension of creating a page alone, it seems that there is not much difference in performance between the two;
let's compare it from another dimension: 更新维度; The process of
using innerHTMLthe update page is to rebuild the html string, and then reset the attribute DOMof the element . innerHTMThis is actually saying that even if we only change a text, we must reset innerHTMLthe property. Resetting innerHTMLattributes is equivalent to destroying all old DOMelements and creating new DOMelements in full.
Let's look at DOMhow the virtual updates the page. It needs to recreate the javascript object (virtual DOM), then compare the old and new virtual DOM, find the changed element and update it.
Another factor is related to the code size of the page. For innerHTMLexample, the larger the page size, the greater the performance consumption when updating. The virtual DOMneeds to update the changing part, which is related to the amount of data that needs to be updated, and has nothing to do with the page size. So the conclusion is that the larger the page, innerHTMLthe greater the performance consumption, far exceeding the virtual DOMperformance consumption.

Operation method JS level DOMlevel
Native JS Pure JS operation DOMoperation
innerHTML Pure JS operation html string DOMparsing Destroy DOM+ DOMcreate, related to page size
virtualDOM Create a virtual DOM+Diff algorithm The update of the changed part DOMis related to the amount of updated data

According to the above analysis and comparison of performance consumption, we can know: native JS < virtual DOM< innerHTML. So if this is the case, why don't we use native JS? This brings up another important question 可维护性.

maintainability

Native JS operations have the best performance, but in practical business project development, we rarely use native JS to develop directly. We used to use it before, but now we use , , JQueryand Angularso Vueon React. This is mainly because it reduces the mental burden on developers and facilitates rapid development and code maintenance.

imperative

Native JS code is generally imperative, that is, what operation I want to do, I will issue any instructions, and focus on the process. A typical imperative framework (library) is JQuery, for example I want to modify the text in a label:

$('#divTag').text('修改后的文案')

Imperative code is basically one instruction after another, telling the program what I want to do. What if I want to modify the className again?

$('#divTag').className('add-class')

Declarative

The declarative style pays more attention to the result. We don’t care what the process of realization is. We just need to tell the framework the result we want, and then help me realize it. Let's implement the same code in a declarative way.

<div id="divTag" class="add-class">修改后的文案</div>

Well, this achieves the result we want, is it very readable? As for how he achieves this result, we generally don’t need to care about it, but here we still need to explain that the Vuebottom layer is still using the imperative code to help us do the encapsulation. After all, the performance of the imperative is the best.

Summarize

When developing Vue projects, it is recommended to use template syntax, because template syntax is more intuitive than using virtual DOM directly (virtual DOM is more flexible than template syntax). The template syntax needs to be converted into a virtual DOM by a compiler, and then rendered into a real DOM node by a renderer. Compared with the traditional innerHTML, the biggest advantage of the virtual DOM is the data update section, which closely updates the changed part and consumes less performance. . In weighing performance consumption, code maintainability, Vue(including React, etc.) mainstream frameworks, the concept of virtualization is used DOM. Of course, this is only part of the reason for using it, because there are also responsive and so on.

Guess you like

Origin blog.csdn.net/gaojinbo0531/article/details/129435763
Recommended