React、Vue 关于虚拟 DOM 的文章经常有这样的表述:因为直接操作真实 DOM 耗性能。妥否?

2022-04-20 11:32:40 +08:00
 Steel

学习 React 过程中,发现很多文章说到: 为什么要用 VDOM ,而不是直接操作真实 DOM ?都有类似这样的表述:直接操作真实 DOM 耗性能,细小的改动都可能导致重绘或重排。

但是如下这样直接操作 DOM ,不比用 VDOM 然后 Diff 后更新 DOM 性能更好吗?

document.getElementById("divId").innerHTML = "update text";

使用 VDOM 的目的更多的是便于管理更新,而不是性能上的考虑?

4022 次点击
所在节点    React
34 条回复
s0f
2022-04-20 11:46:19 +08:00
存在批量修改的情况下,VDOM 可以批量再内存中完成修改,再同步到 DOM 上;
ShadowPower
2022-04-20 11:48:10 +08:00
如果这个操作在短时间内做 1000 次,最后再把它改回原样,用 VDOM 就可以绕过所有重排和绘制工作
许多页面的生成过程,并不能像这个例子一样一步到位
makelove
2022-04-20 11:50:09 +08:00
就问你怎么根据应用状态更新 DOM 吧,要么精细操作,DOM 操作会到处散落且有大量重复片段,要么直接简单无脑全量刷新。
即不想要手动精细操作,又不想低效全量更新 DOM,那只有 VDOM 或类 solidjs 这种,很明显性能比原始全量更新性能高。
gzf6
2022-04-20 11:52:27 +08:00
不谈量级的话这种说法不妥
summer1874
2022-04-20 11:55:21 +08:00
其实就是性能与可维护性的均衡。
声明式的更新性能消耗( vue ,react )= 找出差异的性能消耗 ( diff ,vdom )+ 直接修改的性能消耗( document.createElement 等)。只是目前结合心智负担,可维护性等因素综合考虑,虚拟 dom 还是不错的选择。
murmur
2022-04-20 11:58:08 +08:00
vue react 应该都有 batch 操作,先攒够一堆,然后在更新上去
toesbieya
2022-04-20 11:59:19 +08:00
仿佛在逗我,虚拟 dom 性能永远超不过真实 DOM
statumer
2022-04-20 12:00:07 +08:00
页面上元素少的时候,直接用 DOM 确实有性能优势。比如说写自己博客,直接用 DOM 没什么问题,可以很细粒度的控制状态转移。
页面上有成百上千个元素的时候,你手算最优状态转移是不可能的。所以你直接操作 DOM 完成的不是最优状态转移,但是 vDOM 算出来的是最优状态转移,而 js 计算的开销比 DOM 操作小很多,这时候 vDOM 就有性能优势。
jjwjiang
2022-04-20 12:02:20 +08:00
如果你能精确的明白你哪些 dom 操作会触发重绘,所以能够合并这些操作,那肯定是有性能优势的

问题是没人能做得到
statumer
2022-04-20 12:07:46 +08:00
状态数的增长也会导致你手算最优状态转移的难度暴增。三个状态互相转换你只需要写 3!=6 个 DOM 状态转移函数(K3 完全图)。7 个状态互相转换需要写 7!=5040 个 DOM 状态转移函数(K7 完全图)。
ryncv
2022-04-20 12:14:04 +08:00
vdom 并不能保证 100%优于直接操作 dom ,还是需要看 diff 算法开销,只能说是很大一部分场景下会更加高效。
另外还有就是工程化的因素在里面,更多的是更加便捷的开发效率,不会有人为了追求性能去手动去更新 dom 吧?
otakustay
2022-04-20 12:20:00 +08:00
如果没有 VDOM ,要知道一个状态有没有改变,得去 DOM 上拿对应的属性再和最新的状态比对,但 DOM 的读实在太慢了

https://imgtu.com/i/LrJBee
egoyau
2022-04-20 12:32:47 +08:00
这个问题需要区分场景。
1 、dom 更新频率低:比如静态页面、广告页面,没有数据更新,一次性渲染。操作真实 DOM 性能优于 VDOM 。
2 、dom 更新频率高:有较强的交互性,数据更新频率高。操作真实 DOM 性能劣于 VDOM 。
cyrbuzz
2022-04-20 13:04:51 +08:00
vdom 应该更多的是提供了跨平台的可编程能力,如果仅仅只有直接去操作 DOM 这一种途径,那在非浏览器场景下就不可用,比如服务器端渲染,有 vdom 在其他平台上框架操作的也是 vdom ,只需要实现如何渲染 vdom 就好了。
sweetcola
2022-04-20 13:17:10 +08:00
忘了在哪篇 React 官方的文章看到的了,反正就是说“VDOM 是一个错误的说法,它令别人感觉是 DOM”,不知道有没有记错,这一点也在上面的一些回复也得到体现。

React 更新 DOM 其实也是你这种方法来更新,不然还能怎样用 JS 去更新 DOM 。

举个例子,面对 100 层深度的 DOM ,第 50 层和 99 层要同时被更新,你会怎样做。`document.getElementById("root").innerHTML = '<div>.........</div>'`吗? React 的话会直接找到需要更新的节点并进行替换。
agdhole
2022-04-20 13:18:28 +08:00
keithwhisper
2022-04-20 13:33:14 +08:00
使用 vdom 还有一个 [我认为最有潜力的] 因素是建立了抽象, 前端不再局限于浏览器, 可以拓展到其他载体的可视化中工程中.
Steel
2022-04-20 13:45:30 +08:00
@agdhole 这个可以啊!省去中间商赚差价!解决了楼上各位朋友提到的大规模更新的问题,还直接更新 DOM 。
zilan
2022-04-20 13:45:51 +08:00
楼主应该没做过 jquery 时代(以及之前)的前端开发吧
Steel
2022-04-20 13:47:13 +08:00
@keithwhisper 这个确实如此,RN 的跨平台不正是因为这个 VDOM 吗

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/848093

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX