Vue3渲染优化

  • 编译阶段 template=>render function
  • 渲染阶段 render function=>virtual DOM node
  • 挂载阶段 virtual DOM node=>build webpage
  • patch阶段 oldVnode与newVnode比较更新webpage(diff)

Vue template Explorer进去可以看到优化前后变化

静态提升hoistStatic

vue2.x中无论元素是否参与更新,每次都会重新创建,再渲染

vue3中对于不更新的元素,会做静态提升,只会创建一次,渲染时直接复用即可

import { createVNode as _createVNode, toDisplayString as _toDisplayString, openBlock as _openBlock, createBlock as _createBlock } from "vue"

const _hoisted_1 = /*#__PURE__*/_createVNode("p", null, "我是静态", -1 /* HOISTED */)

export function render(_ctx, _cache, $props, $setup, $data, $options) {
  return (_openBlock(), _createBlock("div", null, [
    _hoisted_1,
    _createVNode("p", null, _toDisplayString(_ctx.change), 1 /* TEXT */)
  ]))
}

事件监听缓存cacheHandlers

缓存绑定事件

<div>
    <button @click="onClick">按钮</button>
</div>

之前

import { createVNode as _createVNode, openBlock as _openBlock, createBlock as _createBlock } from "vue"

export function render(_ctx, _cache, $props, $setup, $data, $options) {
  return (_openBlock(), _createBlock("div", null, [
    _createVNode("button", { onClick: _ctx.onClick }, "按钮", 8 /* PROPS */, ["onClick"])
  ]))
}
//8表示静态标记中的动态属性,我们没必要去对比,因为事件是一样的

之后

import { createVNode as _createVNode, openBlock as _openBlock, createBlock as _createBlock } from "vue"

export function render(_ctx, _cache, $props, $setup, $data, $options) {
  return (_openBlock(), _createBlock("div", null, [
    _createVNode("button", {
      onClick: _cache[1] || (_cache[1] = (...args) => (_ctx.onClick && _ctx.onClick(...args)))
    }, "按钮")
  ]))
}