Vue3.0是如何变快的?
diff算法
vue2.0中虚拟dom是进行全量的对比
vue3中新增了静态标记 patchflag
在与上次虚拟节点进行对比的时候,只对比带有patchflag的节点
并且可以通过flag的信息得知当前节点要对比的具体内容
hoistStatic静态提升
vue2中无论元素是否参与更新,每次都会重新创建,然后再渲染
vue3中对于不参与更新的元素,会做静态提升,只会被创建一次,在渲染时直接复用即可
import { createVNode as _createVNode, toDisplayString as _toDisplayString, openBlock as _openBlock, createBlock as _createBlock } from "vue"
const _hoisted_1 = /*#__PURE__*/_createVNode("p", null, "Xmo", -1 /* HOISTED */)
const _hoisted_2 = /*#__PURE__*/_createVNode("p", null, "Xmo", -1 /* HOISTED */)
const _hoisted_3 = /*#__PURE__*/_createVNode("p", null, "Xmo", -1 /* HOISTED */)
export function render(_ctx, _cache, $props, $setup, $data, $options) {
return (_openBlock(), _createBlock("div", null, [
_hoisted_1,
_hoisted_2,
_hoisted_3,
_createVNode("p", null, _toDisplayString(_ctx.msg), 1 /* TEXT */)
]))
}
// Check the console for the AST
cacheHandlers事件监听器缓存
默认情况下onclick会被视为动态绑定,所以每次都会去追踪它的变化
但是因为是同一个函数,所以没有追踪变化,直接缓存起来复用即可
vue2.0
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 }, "btn", 8 /* PROPS */, ["onClick"])
]))
}
vue3.0开启事件监听后
开启事件监听后的代码大家可能看不懂,但我们只需要观察有没有静态标记即可,在vue3的diff算法中,只有静态标记的才会进行比较,追踪
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(...args)))
}, "btn")
]))
}
// Check the console for the AST
ssr渲染
当有大量静态内容的时候,这些内容会被当做纯字符串推进一个buffer里
即使存在动态的绑定,会通过模板插值嵌入进去,这样会比通过虚拟dom来渲染快上很多
当静态内容大到一定量级的时候,会用_createStaticVNode方法在客户端生成一个static node,这些静态node,会被直接innerHtml,就不需要创建对象,然后根据对象渲染