虚拟DOM同样也是操作DOM,为啥说它快?
贴一段snabbdom Readme的话
Virtual DOM is awesome. It allows us to express our application's viewas a function of its state. But existing solutions were way way too bloated, too slow, lacked features, had an API biased towards OOP and/or lacked features I needed.
把dom树抽象成数据对象
virtual dom 它可以使我们操作这块的数据对象
用数据对象来呈现dom树
在每次视图渲染的时候patch取得最优。
这种做法在我们小量地修改dom是很有好处的。
而在修改大量的数据的时候,不见得能快很多。甚至要慢
而virtual dom还有一个很大的作用是
简化dom操作,让数据与dom之间的关系更直观更简单
不选定场景的讨论都是耍流氓
以上 鄙人一些拙见。望与诸君共探讨
下面是知乎的一个近似链接
网上都说操作真实 DOM 慢,但测试结果却比 React 更快,为什么?
只能说 虚拟DOM
只是减少了一些情况下, 对真实DOM操作的 次数
.
虚拟DOM只是个 JavaScript object
它会在 对比
后再选择更新哪些DOM, 而不会像有些时候, 全部删除再重建.
获取/修改 大量DOM元素的时候,就会先在 虚拟DOM
里 取值 对比
.
然而在某些情况下, 虚拟DOM
也会比 原生DOM
更慢.
这样说吧。
有一个 DOM 结点 d
<div id="d">
<h1 title>{{ title }}</h1>
<div class="intro-container">
{{ intro }}
<p intro>{{ welcome }}</p>
</div>
</div>
上述模版对应的数据是:
var data = {
title: 'just title',
intro: 'it is a title',
welcome: 'welcome welcome'
}
框架已经完成了对数据的绑定(例如 Vue),因此在data上的属性们被重写的时候,会触发 setter,这时候有两个选择:
暴力的用 innerHTML 赋值改变
利用某种方法精确修改 DOM
前者简单可行,但是性能不太好,因为 DOM 操作开销很大。在这种情况下,只要一个属性被重写,整个模版都会被重新渲染,不太好。
后者可以采用虚拟 DOM ,虚拟 DOM 跟普通 DOM 类似,在需要渲染的时候,先在虚拟 DOM 渲染好,然后跟当前普通的 DOM diff 一下,得出需要修改的变化点,然后进行精准的修改,以提升性能。
以上是我的理解。
先举例子:
Virtual DOM :
var element = {
type: 'h1',
attributes: [],
children: []
};
console.log(element);
// 三个
DOM:
var element = document.createElement('h1');
console.log(element);
// 70-80 个属性。
1: 从空间复杂度上来说,减少的不是一点点,如果它是一个树的时候,你可想而知它空间复杂度的问题。
2: 时间复杂度: diff
。减少真实Dom的CRUD次数;注意,这里对真实DOM的操作上的并没有减少,但减少了操作次数,还有就是innerHTML
替代createElement
3: immutable
;
虚拟dom是在内存中维护的dom树,是在实体dom之上的一层抽象。有了这层抽象,不管是查询操作还是修改操作,都是先操作内存中的虚拟dom,在这个过程中可以做很多优化,从而减少对实体dom的操作。举两个例说明,1. 查询一个text标签的值,可以直接从虚拟dom中查找得到,根本不需要查询实体dom。2. 在一次操作中,要修改列表中的两条记录,要修改的元素会先把变更同步到虚拟dom上,然后根据最新的虚拟dom,一次性渲染出最终的实体dom,如果没有虚拟dom,两条记录的修改至少要对应两次对实体dom的操作,显然操作实体dom越频繁,网页速度越慢。
最主要的原因: 假设需要将ui的状态从vdom1变成vdom2, 那么 (比较vdom2 - vdom1 并把不同点更新到dom) 比 (用vdom2完全重建dom
) 快
多一层vdom还可以用来缓存dom状态, 事件代理之类, 不过这不是最重要的因素
13 回答12.8k 阅读
7 回答1.9k 阅读
3 回答1.1k 阅读✓ 已解决
2 回答1.2k 阅读✓ 已解决
6 回答897 阅读✓ 已解决
4 回答1.6k 阅读
6 回答1.1k 阅读
你的知道浏览器的虚拟DOM与真实DOM的区别(注意:需不需要虚拟DOM,其实与框架的DOM操作机制有关):
虚拟DOM不会进行排版与重绘操作
虚拟DOM进行频繁修改,然后一次性比较并修改真实DOM中需要改的部分(注意!),最后并在真实DOM中进行排版与重绘,减少过多DOM节点排版与重绘损耗
真实DOM频繁排版与重绘的效率是相当低的
虚拟DOM有效降低大面积(真实DOM节点)的重绘与排版,因为最终与真实DOM比较差异,可以只渲染局部(同2)
使用虚拟DOM的损耗计算:
直接使用真实DOM的损耗计算:
总之,一切为了减弱频繁的大面积重绘引发的性能问题,不同框架不一定需要虚拟DOM,关键看框架是否频繁会引发大面积的DOM操作