虚拟DOM真的很快吗?

370 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第15天,点击查看活动详情

虚拟DOM真的很快吗?

我们日常使用Vue、React开发,那么相信大家对虚拟DOM并不陌生,如果有些陌生也没关系,我们先大家稍微复习复习

简单复习虚拟DOM(Virtual DOM)

Virtual DOM 是一个 JavaScript DOM 模型,支持元素创建,区别计算和分支操作,提供高效的渲染。 说的通俗一点的就是是使用JS对象模拟DOM节点数据。它是由 React 最先推广使用的,这是为什么要使用虚拟DOM呢?包括后来的 Vue 也是用虚拟DOM,这是为什么呢?这里我们要先稍微了解一下这两个框架的价值。

Vue React 等框架的存在价值

它们的价值在于

  • 组件化
  • 数据视图分离,数据驱动视图 相比于此前的 jQuery 时代,他们做到了数据视图分离,开发时只需要关注业务数据(React 的 state,Vue 的 data)即可,不用在实时的修改 DOM —— 这一点和 jQuery 有了本质区别。
    特别是对于大型的前端项目,将极大的降低开发复杂度,提高稳定性。虚拟DOM在这个中起到了至关重要的作用。

React和Vue的虚拟DOM

React 的 JSX ,Vue 的 template 其实都是语法糖,它们本质上都是一个函数,成为 render 函数

// JSX: <p id="p1">hello world</p>
function render(): VNode {
    return createElement('p', { id: 'p1' }, ['hello world'])
}

执行 render 函数返回的就是一个 vdom 对象,一般叫做 vnode(虚拟节点),对应 DOM Node

每次数据更新(如 React setState)render 函数都会生成 newVnode ,然后前后对比 diff(vnode, newVnode),计算出需要修改的 DOM 节点,再做修改。

虚拟DOM和直接操作DOM哪一个更快?

  • jquery 时代:直接修改 DOM
  • 虚拟DOM:生成 vdom ,进行 diff 运算 --> 修改 DOM

上面的两者,哪个更快?—— 很明显,前者更快。直接操作DOM仅仅需要修改DOM这一步而已,但是虚拟DOM却需要先进行DOM树的构建,diff,然后才进行修改,中间消耗了不少的时间。

但凡事都要有一个业务背景。如果页面功能越来越复杂,直接操作 DOM 代码将会难以阅读和维护,大家更希望要**“数据视图分离,数据驱动视图”**。

在这个前提下,哪个更快? —— 当然是后者。因为业务复杂、代码混乱,将会导致很多无谓的 DOM 操作。

相比于项目复杂之后,越加繁琐的DOM操作,还有考虑到项目之后的维护和代码的易读性虚拟DOM更是优先的选择。

总结

  • 直接进行 DOM 操作永远都是最快的(但要目标明确,不能有无谓的 DOM 操作 —— 这很难)
  • 如果业务复杂,要“数据视图分离,数据驱动视图”,无法直接修改 DOM ,那 vdom 就是一个很好的选择

所以,vdom 并不比 DOM 操作更快(反而更慢,它做了 JS 运算),它只是在某个特定的场景下,无法做到精准 DOM 修改时,一个更优的选择。

扩展

Svelte 不使用 vdom ,它将组件修改,编译为精准的 DOM 操作。和 React 设计思路完全不一样。