为什么我们需要虚拟DOM?



我读了这篇文章https://dev.to/karthikraja34/what-is-virtual-dom-and-why-is-it-faster-14p9

有一个代码示例,示例必须帮助我们理解问题的答案-"为什么我们需要虚拟DOM?">

从文章:

例如:假设我们想从数组中渲染list。我们可以像下面这样做。

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这样的现代框架所做的是,每当state/props中的某些内容发生变化时,将创建一个新的虚拟DOM表示,并将其与之前的表示进行比较。在我们的例子中,唯一的变化是"Apple"Pineapple"帮助"。由于只更改了文本而不是替换整个列表,react将通过以下代码更新DOM:

document.querySelector('li').innerText = "Pineapple"

好了,我明白了Virtual DOM的目的-

通过使用虚拟DOM,我们可以发现更改了什么,并且可以只应用这些更改使用真正的DOM,而不是替换整个DOM

但是,是什么阻止我们在不使用虚拟DOM的情况下编写这些内容呢?

document.querySelector('li').innerText = fruits[0]

但是,是什么阻止我们在不使用虚拟DOM的情况下编写这些内容呢?

document.querySelector('li').innerText = fruits[0]

这将跳过您正在计算的部分:

  • 数组中的第一项,且只有第一项发生了变化
  • 当数组中的项目发生变化时,列表的内容也会发生变化
  • 第一个项目映射到第一个li项目

从您的数据生成一个虚拟DOM,然后应用差异,这些步骤由您负责。

可以自己写代码,但是需要大量的开发时间。

目前有两种主要的框架/库样式渲染方法:

虚拟Dom

一个库,比如React,计算在虚拟DOM中呈现的DOM应该是什么样子,然后将其与实际DOM进行比较并更新差异。

当事件发生时(目前在React中),它们变成了合成事件,从window(可能是文档,现在我正在写它)调度,然后React将它们映射到使用effects更新数据的适当函数,触发虚拟DOM的组件部分的重新渲染-得到的diff和同步与真正的DOM。

DOM

一个库,比如Angular,使用围绕自定义元素创建的class来管理实际更新DOM所需的数据,然后在生命周期的各个点更新自定义元素中的DOM。

当事件发生时,它们从创建事件的元素中被调度,如果需要,它们可以起泡,但大多数情况下,它们被自定义元素的类捕获,以触发自定义元素上的自定义事件,或者管理状态/数据——由于生命周期,它们反过来与DOM同步。

虽然现在单独使用自定义元素有点昂贵,但是一旦连接了Shadow DOM,性能问题就会从渲染转移到自定义开发人员代码或浏览器如何处理Shadow DOM。

每个人都有他们喜欢的理由,虚拟DOM在执行服务器端渲染时更容易,其中基于DOM的方法更符合web标准并利用浏览器。

最新更新