vue更新数据时为什么要diff新旧虚拟dom,直接省去比较的步骤把新的vDom挂载在到实例上再渲染成真实dom不行吗

如题。
现在的patch过程是:
获取新旧vDom => 新旧vDom比较 => 将改动更新到vDom并挂载在vue实例上 => 使用createDocumentFragment更新视图
我的想法是:
获取新旧vDom => 将新vDom挂载在vue实例上 =>
使用createDocumentFragment更新视图
这样还省了一步。
小白不懂,求解释·

阅读 5.6k
6 个回答

不正经回答

既然都不 diff 了,你还要 vDom 干啥?直接更新视图岂不美哉?


正经回答

因为页面上的元素可能会非常多,更新哪部分?全都更新吗?那你这跟页面 F5 刷新了有啥区别?(F5 可能体验反而更好,因为画面闪烁用户能理解,要是压根没刷新、页面咔咔咔一直闪,用户能受得了?)

不全都更新的话,咋识别哪些需要更新?document.getElement 以后然后挨个比较 innerTextstyleclass、……这些属性吗?document.getElement 这种 DOM 操作是要交给浏览器去执行的,一来一回很慢的,数量少的情况下你感觉不到耗时,当页面上元素有几千几万个的时候就很明显了,页面会长时间卡住不动(因为都是同步方法,阻塞的)。

所以才要比较 vDOM,所谓 vDOM 其实就是一堆 JS 对象,都在内存里,直接 JS 就能比较,不用交给浏览器处理,速度上要快很多。

当然了,vDOM 也不是没有缺点,那就是占内存了。这就属于牺牲空间换取时间了。

进行diff,就是为了只做最小更新,来提高渲染的性能。

vDom没法直接挂在页面中,得用vDom生成真实Dom再挂
这样还有问题,你之前input中输入的值怎么办?之前元素绑定的事件还要重新绑定
要把这些问题都解决开销会很大,dom操作都是很耗时的

很简单,你的做法慢得多,副作用也大得多。下次遇到这种情况,自己写个测试跑一跑就知道了。

新手上路,请多包涵

你现在的想法其实就是原来浏览器重绘和回流的步骤,这导致了一个原因:一个简单的页面修改都会导致整体页面的重新计算,这样浪费了大量的系统资源。

为了解决这个,才出现了VDOM和diff算法的方案。

建议看一下浏览器页面的渲染过程,了解一下重绘和回流的原理,就会很好的理解为什么会出现目前的虚拟DOM解决方案。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题