Vue3.0学习——Vue3.0是如何变快的

  • Diff算法优化:

  1. Vue2.0 中的虚拟Dom是全量的对比
  2. Vue3.0 中新增了静态标记(PatchFlag)
    在与上次的虚拟节点进行对比的时候,只对比带有patch flag的节点
    并且可以通过flag的信息知道对比的内容
  • 静态标记

    Vue3 中仅对静态标记标记对象进行比较。

    <div>
      <p>wzl</p>
      <p>wzl</p>
      <p>wzl</p>
      <p>{{msg}}</p>
    </div>
    
    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, "wzl"),
        _createVNode("p", null, "wzl"),
        _createVNode("p", null, "wzl"),
        _createVNode("p", null, _toDisplayString(_ctx.msg), 1 /* TEXT */)
      ]))
    }
    

    可以看到,源码中,对 msg 设计了静态标记,这里是1,后面跟注释 TEXT ,代表这个标签的 TEXT 数据是会动态变化的。

  • hoistStatic静态提升

    1. Vue2中无论元素是否参与更新,每次都会重新创建然后渲染
    2. Vue3中对不参与的更新元素会做静态提升,只会被创建一次,在渲染时直接引用
/*
静态提升之前
*/ 
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, "111"),
    _createVNode("p", null, "222"),
    _createVNode("p", null, _toDisplayString(_ctx.msg), 1 /* TEXT */),
    _createVNode("p", null, "333")
  ]))
}
/*
静态提升之后
不参与的更新元素会做静态提升,只会被创建一次,在渲染时直接引用
*/ 
import { createVNode as _createVNode, toDisplayString as _toDisplayString, openBlock as _openBlock, createBlock as _createBlock } from "vue"

const _hoisted_1 = /*#__PURE__*/_createVNode("p", null, "111", -1 /* HOISTED */)
const _hoisted_2 = /*#__PURE__*/_createVNode("p", null, "222", -1 /* HOISTED */)
const _hoisted_3 = /*#__PURE__*/_createVNode("p", null, "333", -1 /* HOISTED */)

export function render(_ctx, _cache, $props, $setup, $data, $options) {
  return (_openBlock(), _createBlock("div", null, [
    _hoisted_1,
    _hoisted_2,
    _createVNode("p", null, _toDisplayString(_ctx.msg), 1 /* TEXT */),
    _hoisted_3
  ]))
  • cacheHandelers事件侦听器缓存

    默认情况下onClick会被视为动态绑定,所以每次都会追踪它的变化
    但是是同一个函数,所以没有变化,直接缓存起来复用即可
/*
开启事件侦听器缓存之前
*/ 
export function render(_ctx, _cache, $props, $setup, $data, $options) {
  return (_openBlock(), _createBlock("div", null, [
    _createVNode("button", { onClick: _ctx.onClick }, null, 8 /* PROPS */, ["onClick"])
  ]))
}
/*
开启事件侦听器缓存之后
*/ 
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)))
    })
  ]))
}

_createVnode 的第二个属性,从

{ onClick: _ctx.onClick }

变为了

{ onClick: _cache[1] || (_cache[1] = (...args) => (_ctx.onClick(...args))) }

它的意思很明显,onClick 方法被存入 cache。在使用的时候,如果能在缓存中找到这个方法,那么它将直接被使用。如果找不到,那么将这个方法注入缓存。总之,就是把方法给缓存了。

例如:

<div>
  <button @click="onClick" @mouseover="onMouseover">btn</button>
  <button @click="onClick1">btn</button>
</div>
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))),
      onMouseover: _cache[2] || (_cache[2] = (...args) => (_ctx.onMouseover(...args)))
    }, "btn", 32 /* HYDRATE_EVENTS */),
    _createVNode("button", {
      onClick: _cache[3] || (_cache[3] = (...args) => (_ctx.onClick1(...args)))
    }, "btn")
  ]))
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值