为什么需要虚拟DOM?它的本质是什么?

虚拟 DOM 是现代前端框架如 React 和 Vue 等的核心技术之一,它通过使用 JavaScript 对象来模拟真实的 DOM节点,并且通过 Diff 算法来比较新旧虚拟 DOM 树,从而减少对真实 DOM 的操作次数,提高渲染性能。

但是,虚拟 DOM 真的比原生 JS 操作 DOM 快吗?为什么我们需要虚拟 DOM 呢?它到底有什么作用和价值呢?

子辰将从以下几个方面来探讨这个问题:

  • 虚拟DOM与原生JS操作DOM的性能对比
  • 虚拟DOM产生和流行的原因
  • 虚拟DOM的优缺点和适用场景

性能对比

首先,我们来看一下虚拟 DOM 与原生 JS 操作 DOM 的性能对比。

我们可以用一个简单的例子来说明:

我们先看原生 JS 的方式,数据构建成真实 DOM,修改数据的话也是直接修改真实 DOM。

再来看 React 和 Vue 之类的框架,首先也是数据构建,但是框架是将数据构建成虚拟 DOM,然后虚拟 DOM 再构建为真实 DOM。修改的时候再次生成一个新的虚拟 DOM,然后通过 Diff 算法和原来的虚拟 DOM 对比,查找到前后的差异,最后修改真实 DOM。

对虚拟 DOM 和 Diff 算法还不了解的同学,可以看看我们免费的大师课,其中有详细的讲解,这里就不进行深入的探讨了,这并不影响你阅读后续的内容。

这里我们把直接修改真实 DOM 的消耗定义为 A,把找出差异的性能定义为 B,那么就可以得出两者的消耗性能对比。

  • 原生JS更新性能消耗 = A
  • 虚拟DOM更新性能消耗 = A + B

可以看到使用虚拟 DOM 并没有比原生的性能更高,而且最后更新数据也是更改的真实DOM。

在 React 的官网中谈虚拟 DOM 得到时候,没有一句是说提升性能的。

那么既然虚拟 DOM 没有提升性能,反而导致降低了,那为什么还需要它呢?

主要是有两个原因绕不开:

虚拟DOM产生和流行的原因

数据与界面之间复杂的对应关系

像 React 和 Vue 这种框架类的东西,它是一个通用的框架,而他们的框架设计的核心理念就是要把这个数据跟界面对应起来。

当数据变化的时候,要能够正确的去渲染界面,这样就产生了一个问题。

数据跟界面是如何对应的,这就很复杂了,因为一个数据可以用在不同的元素里,而一个元素里有可能有多个数据,它的对应关系是及其复杂的。

而作为通用框架,它是很难预知数据跟界面之间到底如何对应的。

所以如果它采取了一种比较粗暴的简单的办法,只要数据一变,不管那么多,界面全部重新生成一次,那就太夸张了。

如果是使用这种办法的话,我们仅仅修改一个很小的地方,但是框架并不知道我们修改的是哪里,就要导致所有元素都要重新生成,这种做法操作真实 DOM 的代价就太昂贵了。

为了减少对真实 DOM 的操作,它不得不引入虚拟 DOM,就是数据变化了之后,由于不知道界面上哪个地方要更新,所以说既然要全量更新,就不去全量生成真实 DOM 而去全量生成虚拟 DOM,虚拟 DOM 是要全部生成的,然后通过跟之前的虚拟 DOM 对比,找到那个有差异的地方,然后改的它对应的真实 DOM。

它绕这么一大圈其实是不得已而为之的挽救措施,因为它很难做到把数据和最终的界面一一对应,才不得不去引入虚拟 DOM,来减少对真实 DOM 的操作。

不同平台之间界面表达方式的抽象

第二个原因就是抽象,特别是像 React 这种框架,它在设计的时候,并没有把自己想象成为一个,页面级别的应用框架,而是把自己定位成为一个 UI 库,你去翻 React 官网,它并没有说自己是框架。

而 UI 叫做 user interface,表示用户界面,用户界面不一定是网页,它可能是移动端,也可能是桌面应用程度。

那你看不同的平台是不是差异很大,我们平时说的 DOM,通常指的是页面应用,页面里才有 DOM,那小程序、移动端APP、桌面应用程序都是没有 DOM 的。

所以说它为了消除平台之间的差异,于是呢抽象了一个 UI 的表达方式,它使用一个普通对象也就是虚拟 DOM 对象来表达 UI 界面,然后根据不同平台,比如说移动端、桌面应用还是网页,去具体的生成真是的界面,这就是建立了一个抽象层。

基于以上两点原因,所以才有了虚拟 DOM,关于这一点呢,Vue的作者尤雨溪在知乎上也对此做了详细的阐述,感兴趣的同学可以点击链接去查看原文。

虚拟DOM的优缺点和适用场景

虽然虚拟 DOM 并不是为了提升性能而产生和流行的,但是它也并不是没有优点的。虚拟 DOM 的优点主要有以下几个:

  • 提供了一种跨平台的 UI 表达方式,可以让开发者使用统一的语法和逻辑来开发不同平台的应用。
  • 提供了一种数据驱动的 UI 渲染方式,可以让开发者专注于数据和业务逻辑,而不用关心 DOM 操作的细节。
  • 提供了一种高效的 DOM 更新策略,可以避免不必要的 DOM 操作,减少浏览器的重排和重绘。

当然,虚拟 DOM 也有一些缺点,主要有以下几个:

  • 增加了额外的内存开销和计算开销,因为需要创建和维护虚拟 DOM 树,并且进行 Diff 算法。
  • 不能完全替代原生 JS 操作 DOM 的能力,因为有些场景需要直接操作 DOM 才能实现,比如动画、富文本编辑等。
  • 不能完全解决跨平台开发的问题,因为不同平台还是有一些差异和限制,比如小程序、原生应用等。

所以说,虚拟 DOM 并不是万能的,也不是必须的。它只是一种解决方案,适合一些场景,不适合另一些场景。我们需要根据自己的需求和技术栈来选择是否使用虚拟 DOM ,而不是盲目地跟风或者排斥

总结

所以不要人云亦云,要有自己的想法,为什么我们渡一的学生面试通过率能达到百分之七八十,只要敢给面试机会,就能拿 offer,就是当全世界都在说着,错误答案的时候,你是那个唯一能给出正确答案的人,你就能够给面试官致命一击!

本文来源

本文来源自渡一官方公众号:Duing ,欢迎关注,获取最新最全最深入的技术讲解

感谢你阅读本文,如果你有任何疑问或建议,请在评论区留言,如果你觉得这篇文章有用,请点赞收藏或分享给你的朋友!

相关推荐
旧味清欢|10 分钟前
关注分离(Separation of Concerns)在前端开发中的实践演进:从 XMLHttpRequest 到 Fetch API
javascript·http·es6
热爱编程的小曾27 分钟前
sqli-labs靶场 less 8
前端·数据库·less
gongzemin38 分钟前
React 和 Vue3 在事件传递的区别
前端·vue.js·react.js
Apifox1 小时前
如何在 Apifox 中通过 Runner 运行包含云端数据库连接配置的测试场景
前端·后端·ci/cd
-代号95271 小时前
【JavaScript】十四、轮播图
javascript·css·css3
树上有只程序猿1 小时前
后端思维之高并发处理方案
前端
庸俗今天不摸鱼2 小时前
【万字总结】前端全方位性能优化指南(十)——自适应优化系统、遗传算法调参、Service Worker智能降级方案
前端·性能优化·webassembly
QTX187302 小时前
JavaScript 中的原型链与继承
开发语言·javascript·原型模式
黄毛火烧雪下2 小时前
React Context API 用于在组件树中共享全局状态
前端·javascript·react.js
Apifox2 小时前
如何在 Apifox 中通过 CLI 运行包含云端数据库连接配置的测试场景
前端·后端·程序员