Preface
"What are the advantages of Virtual Dom?" This is a common interview question, but the answer is really just a simple and crude sentence "The performance of direct operation of dom and frequent operation of dom is very poor" and it is over? If this is the case, you might as well continue to ask a few more in-depth questions:
- Why is the performance of directly operating the Dom poor?
- What exactly is Virtual Dom? How is it achieved?
- Why can Virtual Dom avoid the problems caused by direct manipulation of dom?
If you find that you are not (yi) too (lian) sure (meng) sure (bi) about these questions, then you might as well read on.
text
Virtual Dom, also known as virtual Dom, is used in both React and Vue. It itself is not a unique design of any technology stack, but a design idea, or design pattern.
DOM
Before introducing the virtual dom, let's first take a look at the real dom corresponding to it:
DOM(Document Object Model)
has two layers:
- Object-based document model (
the object-based representation
); - APIs to manipulate these objects;
Like the following html
code,
<!DOCTYPE html>
<html lang="en">
<head>
<title>Document</title>
</head>
<body>
<h1>Learning Virtual Dom</h1>
<ul class="list">
<li class="list-item">List item</li>
</ul>
</body>
</html>
According to the DOM, it will be represented as a tree as follows: The end of each branch of the tree is a node (node), and each node contains objects and contains some node attributes. This is that based on the object.
Secondly, the DOM allows us to manipulate documents through some APIs, for example:
const listItemOne = document.getElementsByClassName("list-item")[0]; // 获取节点
listItemOne.textContent = "List item one"; // 修改对应的文本内容
const listItemTwo = document.createElement("li"); // 创建一个元素对象
listItemTwo.classList.add("list-item"); // 添加子元素
listItemTwo.textContent = "List item two";
list.appendChild(listItemTwo);
in short. The role of DOM is to associate web pages with scripts (usually Javascript) .
Performance problems caused by DOM operations
So what are the problems with native DOM operations? Here you also need to understand some processes of the browser's work. Generally speaking, the generation of a page requires the following steps:
- Parse HTML and produce the corresponding DOM tree;
- Parse the CSS and generate the corresponding CSS tree;
- Combine the results of 1 and 2 to generate a render tree;
- The layout of the generated page (flow)
- Draw the layout on the display device (paint)
Among them, steps 4 and 5 are actually the often said page rendering , and the rendering process occurs when the page is first loaded, in the subsequent interaction process, DOM operations will also cause rearrangement and redrawing, rendering is Need higher performance cost, especially the process of rearrangement.
So common optimization ideas will mention one point: In order to reduce the number of redraws and rearrangements as much as possible, try to concentrate the operations of changing the dom, because the write operation will trigger redraw or rearrangement, and the browser's rendering queue The mechanism is: when a certain operation triggers reordering or redrawing, the operation is put into the rendering queue first, and when the operation in the queue reaches a certain number or a certain time interval, the browser will execute it in batches. So centralized dom operation can reduce the number of redrawing and rearranging.
On the other hand, regarding the scope of influence of DOM operations: Since the browser is based on a fluid layout, once an element is rearranged, its internal nodes will be affected, while external nodes (sibling nodes, parent nodes, etc.) ) Is that may not be affected. The impact caused by this local rearrangement is relatively small, so it is also necessary to change only the most needed node elements each time as much as possible.
Virtual DOM overview
Virtual DOM was born to solve the above problem. It provides a new way dom
The essence of virtual DOM is a copy of real dom. can operate and update this copy frequently without using DOM API. After all the updates to the virtual DOM, we can see what specific changes need to be made to the original DOM and make the changes in a targeted and optimized way.
This idea can refer to the sand table during marching battles. One of the functions of the sand table is to simulate the arrangement and distribution of the army. Imagine the scenario without the aid of the sand table:
General 1: I think the soldiers of the third team should move 200 meters to the east and lie in ambush on the flanks, and then the messenger ran to inform the soldiers of the third team that they ran 200 meters;
General 2: I think the soldiers of the fourth team should move 200 meters to the west to form an encirclement with the third team, and then the messenger continued to inform that the soldiers of the fourth team should continue to run.
General 3: I think the ambush distance is too far. It's better to be closer. The two teams should move 100 meters in the middle.
Then the poor soldiers continued to run back and forth...
In this process, each marching movement will bring a lot of overhead, and each time the instructions that are still being discussed are executed directly with actual actions, the cost is very high. In fact, when the generals are discussing the arrangement, they can
- first simulate the arrangement on the sand table,
- waited until the ideal square was obtained, and finally notified the soldiers under them to make corresponding adjustments.
This is what Virtual DOM does.
Simplified implementation of Virtual DOM
So what does Virtual DOM look like? According to the previous html file, the corresponding virtual dom
probably as long as this (does not represent the realization of the actual technology stack, but only reflects the core idea):
const vdom = {
tagName: "html",// 根节点
children: [
{ tagName: "head" },
{
tagName: "body",
children: [
{
tagName: "ul",
attributes: { "class": "list" },
children: [
{
tagName: "li",
attributes: { "class": "list-item" },
textContent: "List item"
} // end li
]
} // end ul
]
} // end body
]
} // end html
We use a js
to show the hierarchical relationship of the dom tree and some core attributes, and children
represents the child nodes.
In the previous article, we used native dom to make some updates to ul, and now use Virtual Dom to implement this process:
- Copy a virtual DOM against the current real DOM, and the expected virtual DOM after changes;
const originalDom = {
tagName: "html",// 根节点
children: [
//省略中间节点
{
tagName: "ul",
attributes: { "class": "list" },
children: [
{
tagName: "li",
attributes: { "class": "list-item" },
textContent: "List item"
}
]
}
],
}
const newDom = {
tagName: "html",// 根节点
children: [
//省略中间节点
{
tagName: "ul",
attributes: { "class": "list" },
children: [
{
tagName: "li",
attributes: { "class": "list-item" },
textContent: "List item one" //改动1,第一个子节点的文本
},
{// 改动2,新增了第二个节点
tagName: "li",
attributes: { "class": "list-item" },
textContent: "List item two"
}
]
}
],
};
- Comparison difference
const diffRes = [
{
newNode:{/*对应上面ul的子节点1*/},
oldNode:{/*对应上面originalUl的子节点1*/},
},
{
newNode:{/*对应上面ul的子节点2*/},//这是新增节点,所以没有oldNode
},
]
- After collecting the difference results, it is found that as long as the list node is updated, the pseudo code is roughly as follows:
const domElement = document.getElementsByClassName("list")[0];
diffRes.forEach((diff) => {
const newElement = document.createElement(diff.newNode.tagName);
/* Add attributes ... */
if (diff.oldNode) {
// 如果存在oldNode则替换
domElement.replaceChild(diff.newNode, diff.index);
} else {
// 不存在则直接新增
domElement.appendChild(diff.newNode);
}
})
Of course, the actual frameworks such as vue
and react
in the diff
process are not just that simple, they do more optimizations, for example:
ul
with multiple items, a new node of append
ul
. This change is too costly. diff
process, it may be implemented in a different way and directly use js Generate a new ul
object, and then replace the original ul
. These will be introduced in detail in subsequent articles (probably) that introduce each technology stack.
It can be seen that the core idea of Virtual DOM: first let the expected changes operate on the virtual dom node, and finally apply it to the real DOM uniformly. This operation reduces the chance of redrawing and rearranging to a certain extent, because it does:
- Put the actual dom changes after the diff process, the diff process may be calculated, reducing a lot of unnecessary changes (as the command of General 3 in the previous article, the actual movement of the soldiers is actually reduced);
- For the last necessary dom operations, they are also processed together to fit the browser rendering mechanism and reduce the number of rearrangements;
Summary: Answer the question at the beginning
Now we return to the opening question-"What are the advantages of Virtual Dom?"
Before answering this question, we also need to know:
- First, the browser's DOM engine and JS engine are independent of each other, but share the main thread;
- JS code calling the DOM API must suspend the JS engine, activate the DOM engine, and then activate the JS engine and continue execution after the DOM is redrawn and rearranged;
- If there are frequent DOM API calls, browser vendors will not do "batch processing" optimization, so the overhead of switching and redrawing and rearranging will be very high;
The most critical part of Virtual Dom is that puts the changes that need to be made to the dom first in the js engine for calculations, and when all dom changes in a certain period of time are , 1608110ebde72f. The advantages of this are:
- Reduce the overhead caused by frequent switching between dom engine and js engine;
- Maybe after the calculation and comparison, only part of it needs to be changed in the end, which can reduce a lot of unnecessary redrawing and rearrangement;
- Try to concentrate the necessary Dom operations as much as possible to reduce the number of rearrangements
to sum up
Starting from a common interview question, this article introduces the concepts of Dom and Virtual Dom, as well as possible problems in direct operation of Dom, and illustrates the advantages of Virtual Dom through comparison. For the Virtual Dom diff process and optimization processing methods in the specific technology stack, no more explanations are given, and the concept of Virtual Dom itself is more focused.
Welcome everyone to pay attention to the column, and I hope that you will not hesitate to like and bookmark for your favorite articles. If you have any comments on the style and content, please feel free to exchange private messages.
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。