根据React docs,虚拟DOM是
虚拟DOM(VDOM)是一种编程概念,其中UI的理想或“虚拟”表示形式保存在内存中,并通过诸如ReactDOM之类的库与“真实” DOM同步
在深入研究虚拟DOM之前,先快速介绍一下DOM
文档对象模型(DOM)是对象的数据表示,包括Web上文档的结构和内容
因此,基本上DOM是XML和HTML之类的文档的树状结构表示。我们可以使用DOM添加,删除或更新那些文档中的元素。
什么是虚拟DOM?
虚拟DOM是DOM的表示。实际dom的创建将由浏览器处理。诸如react,vue等之类的现代框架将在内存中创建类似于真实dom的元素树,这被称为虚拟DOM。
例如:
<ul class="fruits">
<li>Apple</li>
<li>Orange</li>
<li>Banana</li>
</ul>
上面的代码可以在虚拟DOM中表示如下。
{
type: "ul",
props: {
"class": "fruits"
},
children: [
{
type: "li",
props: null,
children: [
"Apple"
]
},
{
type: "li",
props: null,
children: [
"Orange"
]
},
{
type: "li",
props: null,
children: [
"Banana"
]
}
]
}
为什么我们需要虚拟DOM?
在SPA不太流行的早期,渲染是在服务器端完成的。因此,对于每个用户交互/请求,服务器将发送一个新页面进行渲染。
对于SPA,将只有一个文档,并且在同一文档中,将完成所有DOM操作。因此,对于复杂的项目,可能会使用许多未优化的DOM操作。
例如:假设我们要从数组中渲染列表。我们可以像下面这样
function generateList(fruits) {
let ul = document.createElement('ul');
document.getElementByClassName('.fruits').appendChild(ul);
fruits.forEach(function (item) {
let li = document.createElement('li');
ul.appendChild(li);
li.innerHTML += item;
});
return ul
}
let fruits = ['Apple', 'Orange', 'Banana']
document.getElementById('#list').innerHtml = generateList(fruits)
现在,如果列表更改,可以再次调用上述方法来生成列表。
fruits = ['Pineapple', 'Orange', 'Banana']
document.getElementById('#list').innerHtml = generateList(fruits)
在上面的代码中,将生成一个新列表,并将其设置在文档中。这种方法的问题是仅更改了单个水果的文本,但是生成了一个新列表并将其更新为DOM。此操作在DOM中很慢。我们可以更改未优化的代码,如下所示。这将减少DOM中的操作数量。
document.querySelector('li').innerText = fruits[0]
未经优化和经过优化的代码的最终结果是相同的,但是未经优化的DOM操作的代价是性能。如果列表的大小很大,那么您可以看到差异。这是我们在较早的框架(如骨干js)中遇到的问题。
那么回答我们的大问题,为什么我们需要虚拟DOM?是解决以上问题。
像react这样的现代框架所做的是,每当状态/属性发生变化时,就会创建一个新的虚拟DOM表示并将其与前一个进行比较。在我们的示例中,唯一的更改是将“ Apple”更改为“ Pineapple”。由于仅更改文本而不是替换整个列表,因此react将通过以下代码更新DOM。
document.querySelector('li').innerText = "Pineapple"
虚拟DOM如何比真实DOM快?
不,虚拟DOM不会比真实DOM快。在内部,虚拟DOM还使用真实DOM来呈现页面或内容。因此,虚拟DOM不可能比真实dom更快。
那为什么每个人都说虚拟DOM更快呢?并不是说虚拟DOM更快。通过使用虚拟DOM,我们可以找出更改的内容,并且可以将更改仅应用于真实DOM,而不必替换整个DOM。
虚拟DOM是减少昂贵的DOM操作的唯一方法吗?
不一定,诸如ember js,angular和svelte之类的其他框架使用不同的方法来解决相同的问题。
结论
虚拟DOM是真实DOM的表示。每当状态更改时,都会创建新的虚拟DOM,并将其与以前的虚拟DOM进行比较。然后DOM操作将应用于那些特定的更改。虚拟DOM的成本是计算与另一个虚拟DOM的差异。对于具有很多组件的大型项目,差异计算将需要时间。您可以在此处详细了解如何处理。
翻译来自
https://dev.to/karthikraja34/what-is-virtual-dom-and-why-is-it-faster-14p9