Vue 3 中的性能提升:综合分析

简介: Vue 3 中的性能提升:综合分析

按照Vue三大块(响应系统,渲染器,编译器),写法,源码角度进行比较

性能优化

数据劫持优化(响应系统)

对于2的Object.defineProperty

  1. 因为需要预先知道要拦截的key是什么,所以并不能检测对象属性的添加和删除
  2. 对于一个较深层级的对象来说,不管是否会访问到深层级的属性,都会进行深度监听,一次性计算量大

Vue.js3使用的proxy不会出现上面的第一个问题。虽然对于深层级对象,仍然需要递归实现,但是它是在proxy的getter操作中赋予响应式。意味着只有访问到这个层级的属性才会建立响应,而不是像2一样直接给整个对象都加上响应。

关于如何深度监听对象可以看我的这篇文章

渲染优化(渲染器)

从双端Diff算法升级为快速Diff算法,具体可以看我的这两篇文章

  1. 双端Diff算法
  2. 快速Diff算法

编译优化(编译器)

通过数据劫持和依赖收集,Vue2数据更新并触发重新渲染的粒度是组件级的。

由于 Vue 使用了模板和组件的组合方式,每个组件都有自己独立的数据对象、依赖收集和渲染上下文。这意味着数据变化只会触发当前组件内部的重新渲染,不会影响其他组件,因此数据更新和重新渲染的粒度是组件级的。

但如果组件中有静态节点,即以后都不会发生改变,但是Diff算法还是会重新比较这些静态节点,尽管我们已经知道这些比较毫无意义。

Vue3在编译阶段对静态模板进行了分析,编译生成了BlockTree,它会指导Diff算法的执行跳过静态节点。。

组合式APi(写法)

这个是对于用户来说改变最大的部分,一种新的代码组织逻辑。但不是Vue的编程范式,他的出现不是为了取代选项式。

但它有着更好的代码逻辑复用能力,在选项式中通过mixin可以使用代码复用,但是使用它可能会导致数据来源不明确和命名冲突

因为不知道数据是从哪个mixin而来,不同mixin中函数名相同可能会产生意料之外的结果。例如我们要复用一个获取鼠标坐标的逻辑

// useMousePosition.js
import {
    ref, onMounted, onBeforeUnmount } from 'vue';

export function useMousePosition() {
   
  const mouseX = ref(0);
  const mouseY = ref(0);

  function handleMouseMove(event) {
   
    mouseX.value = event.clientX;
    mouseY.value = event.clientY;
  }

  onMounted(() => {
   
    window.addEventListener('mousemove', handleMouseMove);
  });

  onBeforeUnmount(() => {
   
    window.removeEventListener('mousemove', handleMouseMove);
  });

  return {
   
    mouseX,
    mouseY,
  };
}
<template>
  <div>
    <p>Mouse X: {
   {
    mouseX }}</p>
    <p>Mouse Y: {
   {
    mouseY }}</p>
  </div>
</template>

<script>
import {
    useMousePosition } from './useMousePosition';

export default {
   
  setup() {
   
    const {
    mouseX, mouseY } = useMousePosition();

    return {
   
      mouseX,
      mouseY,
    };
  },
};
</script>

这样整个的数据流向就很清晰了,并且函数可以接受参数也就更加灵活。多个自定义钩子函数又可以相互组合,而不必担心混合对象的复杂性和顺序问题

源码体积优化

因为包的大小减小,传输时间就会加快,解析包的速度也会加快

  1. 移除了部分API,例如过滤器
  2. 引入树摇减小打包体积。tree-shaking的原理也很简单:依赖ES2015模块语法的静态结构import,export,通过编译阶段的静态分析找到没有导人的模块并打上标记然后在压缩阶段利用压缩工具删除已标记的代码。内置组件例如keepAlive没有被使用就不会被打包进来。

源码层面的优化

源码优化面向的是框架的开发者,目的是让框架本身的代码更易于开发和维护。源码的优化主要体现在使用monorepo和TypeScript开发和管理源码.

Monorepo 是 "monolithic repository" 的缩写,意为“单一仓库”。它是一种代码管理策略,其中在单个版本控制仓库(如 Git 仓库)中存储多个项目或包。这些项目可能是相互关联的,或者是完全独立的。

优点:

  1. 可以更轻松地管理和更新仓库中所有项目的依赖
  2. 可以在单个仓库中构建和测试所有的项目或包,确保它们之间没有冲突

Vue2的源码统一放在src下,3则是放在package下。内部文件都是根据功能划分,但是3的功能划分力度更细致,每个项目之间没有影响,有着自己的API,类型定义和单元测试。

例如:你只想获得Vue提供的响应式能力,对于2来说,你不得不引入整个Vue.js.但是对于3来说,你可以只引用Vue下的reactivity响应库。

2用的是flow,3用的是typeScript。对于typeScript,我的理解是对于框架,组件库很有必要,因为有利于IDE自动补全,并且有更清晰的架构

补充:

RFC

它记录着Vue新功能或功能废弃的讨论,通过它你可以了解到某一功能新增或取消的前因后果。
RfC文档

相关文章
|
14天前
|
缓存 JavaScript UED
Vue3中v-model在处理自定义组件双向数据绑定时有哪些注意事项?
在使用`v-model`处理自定义组件双向数据绑定时,要仔细考虑各种因素,确保数据的准确传递和更新,同时提供良好的用户体验和代码可维护性。通过合理的设计和注意事项的遵循,能够更好地发挥`v-model`的优势,实现高效的双向数据绑定效果。
117 64
|
14天前
|
JavaScript 前端开发 API
Vue 3 中 v-model 与 Vue 2 中 v-model 的区别是什么?
总的来说,Vue 3 中的 `v-model` 在灵活性、与组合式 API 的结合、对自定义组件的支持等方面都有了明显的提升和改进,使其更适应现代前端开发的需求和趋势。但需要注意的是,在迁移过程中可能需要对一些代码进行调整和适配。
|
14天前
|
前端开发 JavaScript 测试技术
Vue3中v-model在处理自定义组件双向数据绑定时,如何避免循环引用?
Web 组件化是一种有效的开发方法,可以提高项目的质量、效率和可维护性。在实际项目中,要结合项目的具体情况,合理应用 Web 组件化的理念和技术,实现项目的成功实施和交付。通过不断地探索和实践,将 Web 组件化的优势充分发挥出来,为前端开发领域的发展做出贡献。
24 8
|
13天前
|
存储 JavaScript 数据管理
除了provide/inject,Vue3中还有哪些方式可以避免v-model的循环引用?
需要注意的是,在实际开发中,应根据具体的项目需求和组件结构来选择合适的方式来避免`v-model`的循环引用。同时,要综合考虑代码的可读性、可维护性和性能等因素,以确保系统的稳定和高效运行。
17 1
|
13天前
|
JavaScript
Vue3中使用provide/inject来避免v-model的循环引用
`provide`和`inject`是 Vue 3 中非常有用的特性,在处理一些复杂的组件间通信问题时,可以提供一种灵活的解决方案。通过合理使用它们,可以帮助我们更好地避免`v-model`的循环引用问题,提高代码的质量和可维护性。
25 1
|
14天前
|
JavaScript
在 Vue 3 中,如何使用 v-model 来处理自定义组件的双向数据绑定?
需要注意的是,在实际开发中,根据具体的业务需求和组件设计,可能需要对上述步骤进行适当的调整和优化,以确保双向数据绑定的正确性和稳定性。同时,深入理解 Vue 3 的响应式机制和组件通信原理,将有助于更好地运用 `v-model` 实现自定义组件的双向数据绑定。
|
17天前
|
JavaScript 前端开发 API
从Vue 2到Vue 3的演进
从Vue 2到Vue 3的演进
31 0
|
17天前
|
JavaScript API 开发者
Vue是如何进行组件化的
Vue是如何进行组件化的
|
19天前
|
JavaScript 前端开发 开发者
vue 数据驱动视图
总之,Vue 数据驱动视图是一种先进的理念和技术,它为前端开发带来了巨大的便利和优势。通过理解和应用这一特性,开发者能够构建出更加动态、高效、用户体验良好的前端应用。在不断发展的前端领域中,数据驱动视图将继续发挥重要作用,推动着应用界面的不断创新和进化。
|
20天前
|
JavaScript 前端开发 开发者
vue学习第一章
欢迎来到我的博客!我是瑞雨溪,一名热爱前端的大一学生,专注于JavaScript与Vue,正向全栈进发。博客分享Vue学习心得、命令式与声明式编程对比、列表展示及计数器案例等。关注我,持续更新中!🎉🎉🎉
23 1
vue学习第一章