这部分主要说两个方面,1是静态提升,2是事件监听缓存
静态提升意思就是说,在以往Vue执行函数的时候,无论是绑定数据的节点还是没有绑定的,都会在render函数执行的时候重新渲染,如下代码所示
import { createVNode as _createVNode, toDisplayString as _toDisplayString, openBlock as _openBlock, createBlock as _createBlock } from "vue" export function render(_ctx, _cache, $props, $setup, $data, $options) { return (_openBlock(), _createBlock("div", null, [ _createVNode("p", null, "HELLO WORLD"), _createVNode("div", null, _toDisplayString(_ctx.msg), 1 /* TEXT */) ])) }
做了静态提升之后,
import { createVNode as _createVNode, toDisplayString as _toDisplayString, openBlock as _openBlock, createBlock as _createBlock } from "vue" const _hoisted_1 = /*#__PURE__*/_createVNode("p", null, "HELLO WORLD", -1 /* HOISTED */) export function render(_ctx, _cache, $props, $setup, $data, $options) { return (_openBlock(), _createBlock("div", null, [ _hoisted_1, _createVNode("div", null, _toDisplayString(_ctx.msg), 1 /* TEXT */) ])) }
静态的节点被提升到渲染函数外部,然后只会在首次的时候执行一下节点创建函数,以后每次渲染都拿外面的那个变量就完事了;
事件监听缓存
在以往的Vue版本中,事件是被当做一种动态属性来监听的,如下所示
import { createVNode as _createVNode, toDisplayString as _toDisplayString, openBlock as _openBlock, createBlock as _createBlock } from "vue" const _hoisted_1 = /*#__PURE__*/_createVNode("p", null, "HELLO WORLD", -1 /* HOISTED */) export function render(_ctx, _cache, $props, $setup, $data, $options) { return (_openBlock(), _createBlock("div", null, [ _hoisted_1, _createVNode("div", null, _toDisplayString(_ctx.msg), 1 /* TEXT */), _createVNode("span", { onClick: _ctx.save }, null, 8 /* PROPS */, ["onClick"]) ])) }
_createVNode("span", { onClick: _ctx.save }, null, 8 /* PROPS */, ["onClick"]) 这部分就是绑定事件的节点,8代表动态属性,具体可参考上一篇;但是我们的事件监听函数,基本上是不会动态改变的;所以再进行监听是完全没有必要的,所以Vue3做了以下优化
import { createVNode as _createVNode, toDisplayString as _toDisplayString, openBlock as _openBlock, createBlock as _createBlock } from "vue" const _hoisted_1 = /*#__PURE__*/_createVNode("p", null, "HELLO WORLD", -1 /* HOISTED */) export function render(_ctx, _cache, $props, $setup, $data, $options) { return (_openBlock(), _createBlock("div", null, [ _hoisted_1, _createVNode("div", null, _toDisplayString(_ctx.msg), 1 /* TEXT */), _createVNode("span", { onClick: _cache[1] || (_cache[1] = (...args) => (_ctx.save && _ctx.save(...args))) }) ])) }
onClick: _cache[1] || (_cache[1] = (...args) => (_ctx.save && _ctx.save(...args))) 由此可见,onClick:不再具有动态属性的标志,不是动态的,自然也不会生成监听了。效率自然也提高了;