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文档

相关文章
|
5天前
|
前端开发 JavaScript API
基于Vue3+Hooks实现4位随机数和60秒倒计时
本文介绍了如何在Vue3中使用Hooks API来实现生成4位随机数和执行60秒倒计时的功能,并提供了详细的代码示例和运行效果展示。
23 1
基于Vue3+Hooks实现4位随机数和60秒倒计时
|
1天前
|
JSON JavaScript 前端开发
Vue3在工作中使用的一些经验总结
这篇文章是关于Vue 3项目中使用TypeScript的一些经验总结,包括如何配置TSLint进行代码规范和类型检查,以及如何将现有的JavaScript代码迁移到TypeScript的步骤和注意事项。
Vue3在工作中使用的一些经验总结
|
4天前
|
JavaScript 算法 API
Vue 3有哪些新特性
【8月更文挑战第16天】Vue 3有哪些新特性
25 1
|
5天前
|
JavaScript UED
如何在Vue3项目中使用防抖节流技巧
在Vue 3项目中使用防抖和节流技巧以优化组件性能,包括使用`lodash`库和自定义实现这两种方法。
10 0
如何在Vue3项目中使用防抖节流技巧
|
1天前
|
JavaScript 前端开发 API
Vue3入门
Vue3入门
4 0
|
4天前
|
JavaScript
创建 Vue3 项目
创建 Vue3 项目
11 0
|
5天前
|
JavaScript
在Vue3+ElementPlus项目中使用具有懒加载的el-tree树形控件
在Vue 3和Element Plus项目中实现具有懒加载功能的el-tree树形控件,以优化大数据量时的页面性能。
14 0
|
1天前
|
JavaScript
Vue学习之--------路由的query、params参数、路由命名(3)(2022/9/5)
这篇文章详细介绍了Vue路由中的query参数、命名路由、params参数以及props配置的使用方式,并通过实际项目案例展示了它们在开发中的应用和测试结果,同时解释了`<router-link>`的`replace`属性如何影响浏览器历史记录。
Vue学习之--------路由的query、params参数、路由命名(3)(2022/9/5)
|
1天前
|
JavaScript
Vue学习之--------VueX(2022/8/31)
这篇文章是关于VueX的基础知识介绍,涵盖了VueX中的state、mutations、getters和actions的定义和使用,以及Action提交mutation而非直接变更状态,以及mutations的同步执行特性。
Vue学习之--------VueX(2022/8/31)
|
1天前
|
JavaScript
Vue学习之--------深入理解Vuex之多组件共享数据(2022/9/4)
这篇文章通过一个实际的Vue项目案例,演示了如何在Vuex中实现多组件间共享数据。文章内容包括在Vuex的state中新增用户数组,创建Person.vue组件用于展示和添加用户信息,以及在Count组件中使用Person组件操作的数据。通过测试效果展示了组件间数据共享和状态更新的流程。
Vue学习之--------深入理解Vuex之多组件共享数据(2022/9/4)