虚拟 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 ,欢迎关注,获取最新 、最全 、最深入的技术讲解
感谢你阅读本文,如果你有任何疑问或建议,请在评论区留言,如果你觉得这篇文章有用,请点赞收藏或分享给你的朋友!