vue3的效率提升主要表现在哪些方面?

一、静态提升

1、针对于静态节点,没有绑定动态内容

  例如<h1>你好<h1/>,这种属于永久不变的静态节点,vue2的处理方式如下

// vue2的静态节点
render() {
    createVNode("h1", null, '你好')
}

  这种处理方式,每次渲染时都会新建一个节点  

  vue3的处理方式如下,用一个变量接收创建的节点,每次渲染时调用这个变量即可,这样节点  就只会创建一次

//vue3的静态节点
const hoisted = createVNode("h1", null, "你好")
function render() {
    // 直接调用hoisted即可
}
2、针对于动态绑定内容,但是静态属性的情况,静态属性会被提升
<div class="user">
    {{user.name}}
</div>

vue3的处理方式是将静态属性用变量接收,每次创建动态节点时,调用变量

const hoisted = { class: "user" }
function render(){
  createVNode("div", hoisted, user.name)
}

二、预字符串化

<div class="menu-bar-container">
  <div class="logo">
    <h1>logo</h1>
  </div>
  <ul class="nav">
    <li><a href="">menu</a></li>
    <li><a href="">menu</a></li>
    <li><a href="">menu</a></li>
    <li><a href="">menu</a></li>
    <li><a href="">menu</a></li>
  </ul>
  <div class="user">
    <span>{{ user.name }}</span>
  </div>
</div>

当编译器遇到大量连续的静态内容,会直接将其编译为一个普通字符串节点

  

        

注:预字符串化只针对于连续出现的大量的静态节点,一般为超过20个的连续静态节点

三、缓存事件处理函数

在调用render函数时,会调用cache缓存,判断cache[0]是否存在,存在即调用,不存在即赋值调用

<button @click="count++">plus</button>

// vue2的处理方式
render(ctx){
  return createVNode("button", {
    onClick: function($event){
      ctx.count++;
    }
  })
}

// vue3的处理方式
render(ctx, _cache){
  return createVNode("button", {
    onClick: cache[0] || (cache[0] = ($event) => (ctx.count++))
  })
}

四、Block Tree

vue2在对比新旧树的时候,并不知道哪些节点是静态的,哪些是动态的,因此只能一层一层比较,这就浪费了大部分时间在比对静态节点上

五、PatchFlag(静态标记)

在vue2中,每次更新diff,都是全量对比,Vue3则只对比带有标记的,这样大大减少了非动态内容的对比消耗

<div class="user" :class="user.name">
    <span :class="user.name">{{ user.name }}</span>
</div>

TEXT = 1,   // 1 文本节点
CLASS = 1 << 1,  // 2  class
STYLE = 1 << 2,  // 4 style
PROPS = 1 << 3,  // 8 属性,不包括类名和样式
FULL_PROPS = 1 << 4,  // 16  key,当 key 变化时需要完整的 diff 算法做比较
HYDRATE_EVENTS = 1 << 5,  // 32 表示带有事件监听器的节点
STABLE_FRAGMENT = 1 << 6,   // 64 一个不会改变子节点顺序的 Fragment
KEYED_FRAGMENT = 1 << 7, // 128 带有 key 属性的 Fragment
UNKEYED_FRAGMENT = 1 << 8, // 256 子节点没有 key 的 Fragment
NEED_PATCH = 1 << 9,   // 512  表示只需要non-props修补的元素 (non-props不知道怎么翻才恰当~)
DYNAMIC_SLOTS = 1 << 10,  // 1024 动态的solt
DEV_ROOT_FRAGMENT = 1 << 11, //2048 表示仅因为用户在模板的根级别放置注释而创建的片段。 这是一个仅用于开发的标志,因为注释在生产中被剥离。
 
//以下两个是特殊标记
HOISTED = -1,  // 已提升的静态vnode,更新时调过整个子树
BAIL = -2 // 差异算法应该退出优化模式

注:1<<n  表示十六进制中 1向左移n位, 如: 1<<3 ,则表示 0001 变成 0100 即:8

  • 12
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值