前端实习面试准备-如何理解虚拟dom

74 阅读3分钟

什么是虚拟dom?

vue官方文档给出的说法是:

虚拟 DOM (Virtual DOM,简称 VDOM) 是一种编程概念,意为将目标所需的 UI 通过数据结构“虚拟”地表示出来,保存在内存中,然后将真实的 DOM 与之保持同步。这个概念是由 React 率先开拓,随后被许多不同的框架采用,当然也包括 Vue。

const vnode = {
  type: 'div',
  props: {
    id: 'hello'
  },
  children: [
    /* 更多 vnode */
  ]
}

虚拟dom一定比真实dom快吗?

这里重点有引用一下尤桑2016年在知乎上的一篇回答:

www.zhihu.com/question/31…

重点理解以下几点:

  1. 原生 DOM 操作 vs. 通过框架封装操作。 这是一个性能 vs. 可维护性的取舍。框架的意义在于为你掩盖底层的 DOM 操作,让你用更声明式的方式来描述你的目的,从而让你的代码更容易维护。没有任何框架可以比纯手动的优化 DOM 操作更快,因为框架的 DOM 操作层需要应对任何上层 API 可能产生的操作,它的实现必须是普适的。框架给你的保证是,你在不需要手动优化的情况下,我依然可以给你提供过得去的性能。

  2. 对 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 操作来说,依然便宜了太多。

  1. 性能比较也要看场合
  • 初始渲染:Virtual DOM > 脏检查 >= 依赖收集
  • 小量数据更新:依赖收集 >> Virtual DOM + 优化 > 脏检查(无法优化) > Virtual DOM 无优化
  • 大量数据更新:脏检查 + 优化 >= 依赖收集 + 优化 > Virtual DOM(无法/无需优化)>> MVVM 无优化

在我看来 Virtual DOM 真正的价值从来都不是性能,而是它

  1. 为函数式的 UI 编程方式打开了大门;
  2. 可以渲染到 DOM 以外的backend,比如 ReactNative。

总结:

  1. 框架的dom需要具有普适性,能给的保证是在不需要手动优化的情况下保证一个过得去的性能。
  2. 相对于innerHTML的方式,Virtual DOM在操作真实Dom时的节约还是更有决定性意义的。
  3. 在比较性能的时候,要分清楚初始渲染、小量数据更新、大量数据更新这些不同的场合。