博客
关于我
Vue.js 学习总结(13)—— Vue3 version 计数介绍
阅读量:801 次
发布时间:2023-02-17

本文共 2340 字,大约阅读时间需要 7 分钟。

Vue3.5性能优化:从version计数到懒更新的深度解析

前言

Vue3.5版本引入了两个关键性能提升机制:version计数和双向链表。其中,version计数是最为重要的性能优化之一,其在依赖追踪中的作用堪称关键。通过version计数,Vue能够快速判断依赖项是否有更新,从而决定是否执行懒更新(lazy update)。这一机制极大地减少了不必要的计算开销,提升了应用的运行效率。

version计数的核心作用

version计数机制的核心在于通过版本号来标记依赖项是否有更新。当一个依赖项发生变化时,其版本号会自增。Vue在处理依赖更新时,会首先比较当前版本号与目标的版本号。如果当前版本号与目标版本号一致,则说明依赖项没有变化,不需要触发更新;如果不一致,则表示依赖项已经发生了变化,需要进行更新。

懒更新机制的工作原理

懒更新(Lazy Update)是Vue性能优化的另一大亮点。懒更新的核心思想是:只有当依赖项的值被使用时,才会触发其回调函数(computed函数或effect函数)进行更新。这意味着,计算结果只会在需要的时候进行,避免了不必要的计算。

以下是一个简单的示例:

const a = ref(0)
const b = ref(0)
const check = ref(true)
const c = computed(() => {
console.log('computed')
if (check.value) {
return a.value
} else {
return b.value
}
})
a.value++ // step 1
effect(() => {
console.log('effect')
c.value
c.value
})
b.value++ // step 2
check.value = false // step 3
b.value++ // step 4

运行以上代码,打印结果会是:effectcomputedcomputedeffectcomputedeffect

为什么会是这样的结果?

  • step 1:调用computed函数时,fn不会立即执行,只有在c.value被访问时才会执行。
  • step 2:由于cfn未执行,a没有订阅者,因此不会打印日志。
  • step 3effect会立即执行,先打印effect,第一次读取c.value时打印computed,因为cfn未执行,结果没有变化。
  • step 4:虽然b.value有更新,但c的依赖项仅为acheck,因此cfn不会执行。
  • step 5check.value有更新,cfn执行,打印computed,此时c的依赖项变为checkbc更新,导致effect重新执行,打印effect
  • step 6:逻辑与step 5一致,打印computedeffect
  • version计数在懒更新中的作用

    在懒更新过程中,version计数器发挥了至关重要的作用。它通过跟踪依赖项的更新版本号,帮助Vue快速判断是否需要触发懒更新。具体来说,version计数器分为以下几个方面:

  • 全局版本号 (globalVersion):这是一个全局计数器,每当任何响应式对象发生更新时,它会自增。这用于快速判断是否有依赖项需要更新。
  • 依赖对象的版本号 (Dep.version):每个依赖项都有自己的版本号,当依赖项发生变化时,其版本号也会自增。
  • 双向链表中的版本号:双向链表不仅包含订阅者和依赖项,还包含版本号信息,这进一步优化了依赖更新的过程。
  • 全局版本号的实现

    全局版本号 (globalVersion) 的实现逻辑非常简单:

    export let globalVersion = 0

    trigger函数被调用时,会检查目标对象的依赖项集合 (depsMap) 是否存在。如果不存在,说明目标对象没有依赖项,直接自增globalVersion并结束流程;如果存在,则继续执行依赖项的更新。

    依赖项更新的具体流程

  • 触发依赖更新:当某个依赖项发生变化时,trigger函数会被调用。
  • 检查全局版本号:如果目标对象的依赖项集合不存在,globalVersion自增并结束流程。
  • 收集依赖项:遍历目标对象的依赖项集合,准备进行更新。
  • 批处理依赖更新:使用startBatchendBatch进行批处理,确保依赖更新不会互相干扰。
  • 通知订阅者:通过双向链表通知所有相关订阅者进行更新。
  • 双向链表的优势

    双向链表的引入使得依赖更新变得更加高效。它不仅包括订阅者的依赖链表(横向),还包括响应式值对应的订阅者的链表(纵向)。这种双向的依赖管理方式,极大地减少了内存泄漏和不必要的计算开销。

    内存优化的关键

    computed函数的执行过程中,通过prepareDepscleanupDeps两个辅助函数,优化了内存管理。prepareDeps会将依赖链表上的节点版本号重置为-1,表示这些依赖项正在被计算。cleanupDeps则会清理不再需要的依赖节点,避免内存泄漏。

    总结

    version计数和懒更新是Vue3.5性能优化的两大核心机制。通过version计数,Vue能够快速判断依赖项是否有更新,从而决定是否需要执行懒更新。双向链表的引入则进一步优化了依赖管理,使得内存管理更加高效,性能提升显著。

    在实际应用中,version计数器和懒更新机制的结合,使得Vue能够在不影响用户体验的情况下,实现高效的状态更新和依赖管理。这不仅提升了应用的运行效率,也为开发者提供了更高效的开发体验。

    转载地址:http://runfk.baihongyu.com/

    你可能感兴趣的文章
    object detection训练自己数据
    查看>>
    object detection错误Message type "object_detection.protos.SsdFeatureExtractor" has no field named "bat
    查看>>
    object detection错误之Could not create cudnn handle: CUDNN_STATUS_INTERNAL_ERROR
    查看>>
    object detection错误之no module named nets
    查看>>
    Object of type 'ndarray' is not JSON serializable
    查看>>
    Object Oriented Programming in JavaScript
    查看>>
    object references an unsaved transient instance - save the transient instance before flushing
    查看>>
    Object.assign用法
    查看>>
    Object.create
    查看>>
    Object.keys()的详解和用法
    查看>>
    objectForKey与valueForKey在NSDictionary中的差异
    查看>>
    Objective - C 小谈:消息机制的原理与使用
    查看>>
    OBJECTIVE C (XCODE) 绘图功能简介(转载)
    查看>>
    Objective-C ---JSON 解析 和 KVC
    查看>>
    Objective-C 编码规范
    查看>>
    Objective-Cfor循环实现Factorial阶乘算法 (附完整源码)
    查看>>
    Objective-C——判断对象等同性
    查看>>
    objective-c中的内存管理
    查看>>
    Objective-C之成魔之路【7-类、对象和方法】
    查看>>
    Objective-C享元模式(Flyweight)
    查看>>