什么是虚拟dom?
vue官方文档给出的说法是:
虚拟 DOM (Virtual DOM,简称 VDOM) 是一种编程概念,意为将目标所需的 UI 通过数据结构“虚拟”地表示出来,保存在内存中,然后将真实的 DOM 与之保持同步。这个概念是由 React 率先开拓,随后被许多不同的框架采用,当然也包括 Vue。
const vnode = {
type: 'div',
props: {
id: 'hello'
},
children: [
/* 更多 vnode */
]
}
虚拟dom一定比真实dom快吗?
这里重点有引用一下尤桑2016年在知乎上的一篇回答:
重点理解以下几点:
-
原生 DOM 操作 vs. 通过框架封装操作。 这是一个性能 vs. 可维护性的取舍。框架的意义在于为你掩盖底层的 DOM 操作,让你用更声明式的方式来描述你的目的,从而让你的代码更容易维护。没有任何框架可以比纯手动的优化 DOM 操作更快,因为框架的 DOM 操作层需要应对任何上层 API 可能产生的操作,它的实现必须是普适的。框架给你的保证是,你在不需要手动优化的情况下,我依然可以给你提供过得去的性能。
-
对 React 的 Virtual DOM 的误解。 React 从来没有说过 “React 比原生操作 DOM 快”。React 的基本思维模式是每次有变动就整个重新渲染整个应用。如果没有 Virtual DOM,简单来想就是直接重置 innerHTML。很多人都没有意识到,在一个大型列表所有数据都变了的情况下,重置 innerHTML 其实是一个还算合理的操作... 真正的问题是在 “全部重新渲染” 的思维模式下,即使只有一行数据变了,它也需要重置整个 innerHTML,这时候显然就有大量的浪费。 我们可以比较一下 innerHTML vs. Virtual DOM 的重绘性能消耗:
-
innerHTML: render html string O(template size) + 重新创建所有 DOM 元素 O(DOM size)
-
Virtual DOM: render Virtual DOM + diff O(template size) + 必要的 DOM 更新 O(DOM change)
Virtual DOM render + diff 显然比渲染 html 字符串要慢,但是!它依然是纯 js 层面的计算,比起后面的 DOM 操作来说,依然便宜了太多。
- 性能比较也要看场合
- 初始渲染:Virtual DOM > 脏检查 >= 依赖收集
- 小量数据更新:依赖收集 >> Virtual DOM + 优化 > 脏检查(无法优化) > Virtual DOM 无优化
- 大量数据更新:脏检查 + 优化 >= 依赖收集 + 优化 > Virtual DOM(无法/无需优化)>> MVVM 无优化
在我看来 Virtual DOM 真正的价值从来都不是性能,而是它
- 为函数式的 UI 编程方式打开了大门;
- 可以渲染到 DOM 以外的backend,比如 ReactNative。
总结:
- 框架的dom需要具有普适性,能给的保证是在不需要手动优化的情况下保证一个过得去的性能。
- 相对于innerHTML的方式,Virtual DOM在操作真实Dom时的节约还是更有决定性意义的。
- 在比较性能的时候,要分清楚初始渲染、小量数据更新、大量数据更新这些不同的场合。