Vue 3.6 推试验性 Vapor Mode,逐步弃 VDOM!它凭元素级定点更新破 VDOM 性能瓶颈,借抽象代码兼容跨平台,却存编译压力与产物体积问题,带你看透 Vue 性能进化方向!

引言

灵魂三问

一、为什么要干掉vdom?

在之前vue中视图更新的最小单位是组件,只要是render依赖的响应式数据变了,那render函数就会重新执行,重新生成vdom -> diff -> 真实渲染,这样的方式在性能上有两个瓶颈:

  1. 重新计算的多余性能消耗
    因为是整个组件一起重新计算出vdom,然后去更新,尽管在运行时vue对这块儿已经做了很多优化了,例如:组件级别的缓存与跳过等,但是无论如何都会有不必要的计算出现,最理想的情况应该是只重新计算直接依赖变化的响应式的数据的节点信息;
  2. 多余的dom更新/生成
    在重新计算出整个组件的vdom之后,这些vdom再拿去diff,然后把diff出来的vdom拿去真实渲染更新,但是尽管diff算法已经优化成这样了,但是在某些场景下依然会产生多余的dom更新/生成。

虽然vue之前也搞了特别多的优化,但是以上两个问题依然是vdom模式所无法避免的问题,所以要达到无限接近原生的最优性能,只能逐步移除vdom模式。

二、为什么Vapor Mode比Vdom 模式更快?

这个问题其实比较简单,因为Vapor是元素级别的,类似svelte,响应式数据更新,会去定点更新对应的元素,而不是整个组件一起更新,所以也就没有vdom那些瓶颈。

三、没有Vdom层,Vue怎么解决跨平台问题?

要知道vdom 模式的两大优点就是:

  1. 减少多余的dom更新,对比直接写原生,性能提高
  2. 作为一层抽象,去描述ui,便于跨平台

以前的跨平台框架(uniapp等)是怎么做的?
直接重写Vue的渲染器,Vue默认提供的渲染器实现是浏览器api,所以其他平台只需要把渲染器这层用其他的api实现,移动端就用移动端那套来实现就行了。
现在没有vdom来描述ui,那渲染器怎么搞?
要理解这个的话,需要先知道vue中关于模板到渲染器去生成UI的整个运行机制

image.png
其他节点,大家都比较清楚,关于“抽象层渲染代码”这块儿,我觉得可能需要单独解释一下,之前的理解中渲染器作用应该是vdom转ui,但是实际上在渲染器之前就会生成一层原子化的抽象层渲染代码,渲染器的作用可以理解成是把这层抽象代码转成真实ui。
抽象代码示意(并非真实编译产物):

<template>
    dkh
</template>
const text = createText('dkh');

// 具体实现放渲染器中
function createText(txt = ''){
 ....
}

可以看到这层抽象代码其实是原子化的,所以可以看作在渲染器中,要做的就只是实现这些渲染函数,而不是单纯的vdom转ui的逻辑。
所以本来vdom转ui这套逻辑已经是通过这层抽象渲染代码解耦了的,所以即使移除了vdom,那些基于vue的跨端框架也无需大量的改动就能完成适配。而vue团队关于这块儿要做的也只是修改vdom转抽象代码的逻辑,这对下层开发者理论上也应该是无感的。

Vapor Mode目前的问题

OK,前面说了这么多,貌似Vapor应该是碾压Vdom,但是现在的Vapor Mode也只是试验阶段,依然也存在一些问题的。

  1. 把运行时Vdom的计算和转换等全部取消,把压力都给到了编译时,编译过程可能出问题且时间长
  2. 如果渲染的组件过多,可能会出现大量重复代码,导致编译产物体积过大

其实最主要的也是第二个问题,Svelte也有类似的问题,但是就目前的观察Vapor这个问题还没有很明显出现,另外就是vapor目前只是试验阶段,目前是vapor和vdom可以兼容,后面可能尤大看市场认可度比较高的话,就会在vue4中彻底移除vdom了吧。

最后感谢大家的阅读,以上是我个人关于Vapor的一些理解,可能有些说的不合适的地方,有不同见解的同学可以在评论一起探讨一下

本站提供的所有下载资源均来自互联网,仅提供学习交流使用,版权归原作者所有。如需商业使用,请联系原作者获得授权。 如您发现有涉嫌侵权的内容,请联系我们 邮箱:[email protected]