vue3,对比 vue2 有什么优点?

本文分享自华为云社区《【云驻共创】vue3相比 vue2 的十项优点》,作者: 海拥。
Vue3新版本的理念成型于 2018 年末,当时的 Vue 2 已经有两岁半了 。比起通用软件的生命周期来这好像也没那么久,Vue3在2020年正式推出,在源码和API都有较大变化,性能得到了显著的提升,比Vue2.x快1.2~2倍 。
其中,一些比较重要的优点有:
diff算法的优化;hoistStatic 静态提升;cacheHandlers事件侦听器缓存;ssr渲染;更好的Ts支持;Compostion API: 组合API/注入API;更先进的组件;自定义渲染API;按需编译,体积比vue2.x更小;支持多根节点组件等 。
下面我们就来具体说说vue3 的优点 。
优点1:diff算法的优化vue2中的虚拟dom是全量的对比(每个节点不论写死的还是动态的都会一层一层比较,这就浪费了大部分事件在对比静态节点上)
vue3新增了静态标记(patchflag)与上次虚拟节点对比时,只对比带有patch flag的节点(动态数据所在的节点);可通过flag信息得知当前节点要对比的具体内容 。
例如:下面的模板包含一个div,div内包含三个段落,其中前两个段落是静态固定不变的,而第三个段落的内容绑定的msg属性,当msg改变的时候,Vue会生成新的虚拟DOM然后和旧的进行对比 。
<div> <p>云驻共创</p> <p>如何评价 vue3</p> <p>{{msg}}</p></div>当视图更新时,只对动态节点部分进行diff运算,减少了资源的损耗 。Patchflag是个枚举,取值为1代表这个元素的文本是动态绑定的,取值为2代表元素的class是动态绑定的 。
优点2:hoistStatic 静态提升vue2无论元素是否参与更新,每次都会重新创建然后再渲染 。vue3对于不参与更新的元素,会做静态提升,只会被创建一次,在渲染时直接复用即可 。例如:下面我们利用Vue 3 Template Explorer,来直观的感受一下:
<div><div>共创1</div><div>共创2</div><div>{{name}}</div></div>静态提升之前
export function render(...) {return (_openBlock(),_createBlock('div', null, [_createVNode('div', null, '共创1'),_createVNode('div', null, '共创2'),_createVNode('div',null,_toDisplayString(_ctx.name),1 /* TEXT */),]))}静态提升之后
const _hoisted_1 = /*#__PURE__*/ _createVNode('div',null,'共创1',-1 /* HOISTED */)const _hoisted_2 = /*#__PURE__*/ _createVNode('div',null,'共创2',-1 /* HOISTED */)export function render(...) {return (_openBlock(),_createBlock('div', null, [_hoisted_1,_hoisted_2,_createVNode('div',null,_toDisplayString(_ctx.name),1 /* TEXT */),]))}从以上代码中我们可以看出,_hoisted_1 和_hoisted_2两个方法被提升到了渲染函数 render 之外,也就是我们说的静态提升 。通过静态提升可以避免每次渲染的时候都要重新创建这些对象,从而大大提高了渲染效率 。
优点3:cacheHandlers 事件侦听器缓存vue2.x中,绑定事件每次触发都要重新生成全新的function去更新,cacheHandlers 是Vue3中提供的事件缓存对象,当 cacheHandlers 开启,会自动生成一个内联函数,同时生成一个静态节点 。当事件再次触发时,只需从缓存中调用即可,无需再次更新 。
默认情况下onClick会被视为动态绑定,所以每次都会追踪它的变化,但是同一个函数没必要追踪变化,直接缓存起来复用即可 。
例如:下面我们同样是通过Vue 3 Template Explorer,来看一下事件监听器缓存的作用:
<div><div @click="todo">做点有趣的事</div></div>该段 html 经过编译后变成我们下面的结构(未开启事件监听缓存):
export function render(...) {return (_openBlock(),_createBlock('div', null, [_createVNode('div',{ onClick: _ctx.todo}, '做点有趣的事', 8 /* PROPS */,['onClick']),]))}当我们开启事件监听器缓存后:
export function render(...) {return (_openBlock(),_createBlock('div', null, [_createVNode('div',{onClick://开启监听后_cache[1] || (_cache[1] = (...args) =>_ctx.todo(...args)),},'做点有趣的事'),]))}我们可以对比开启事件监听缓存前后的代码,转换之后的代码, 大家可能还看不懂, 但是不要紧,我们只需要观察有没有静态标记即可,在Vue3的diff算法中, 只有有静态标记的才会进行比较, 才会进行追踪 。
优点4:ssr渲染Vue2 中也是有 SSR 渲染的,但是 Vue3 中的 SSR 渲染相对于 Vue2 来说,性能方面也有对应的提升 。
当存在大量静态内容时,这些内容会被当作纯字符串推进一个 buffer 里面,即使存在动态的绑定,会通过模版插值潜入进去 。这样会比通过虚拟 dmo 来渲染的快上很多 。


推荐阅读