vue 历程记

目录

  • 前言
  • 一、源码优化
    • 1、vue3.x 采用 monorep 的理念来管理源码
    • 2、vue3.x 源码采用 TypeScript 开发
  • 二、性能优化
    • 1、减少源码的体积
    • 2、数据劫持优化
    • 3、编译优化
      • (1)、编译粒度的优化
  • 三、语法 API 的优化
    • 1、优化了编码的逻辑组织
    • 2、优化了代码的逻辑复用


前言

在这里插入图片描述

一、源码优化

1、vue3.x 采用 monorep 的理念来管理源码

截止2023年年底,最新的 vue2.x 源码 和 vue3.x 源码 的核心部分,项目结构的“管理方式”对比:
在这里插入图片描述在这里插入图片描述
(左边是 vue2.x 源码目录)(右边是 vue3.x 源码目录)

可见:

  • vue2.x 的源码托管在 src 目录下,依据功能拆分成了不同的模块;vue3.x 的源码主要是使用 monorep 的理念来开发和维护的——根据功能将不同的模块拆分到 packages 目录下面。这种变化,具有以下优点:
    • 每个 package 有各自的 API、类型定义 和 测试,这使得模块拆分更细化、职责更明确、依赖关系更明确,更易于开发者使用,从而提升了自身代码的可维护性。
    • 部分 package(比如:reactive 响应式库)可以独立于 vue.js 使用,减小了引用包的体积大小。

2、vue3.x 源码采用 TypeScript 开发

vue3.x 源码全面采用 TypeScript 开发,在编码期间 TS 会自动做类型检查,避免一些类型错误导致的问题。
vue2.x 源码一开始是用 javascript 开发的,类型检查是用 Flow.js 实现的。在 vue3.0 推出以后,用 TypeScript 重构过了。

二、性能优化

1、减少源码的体积

移除了一些冷门的 feature。比如:Filters(过滤器)、inline-template等(https://blog.csdn.net/m0_62018311/article/details/131011249)
引入 tree-shaking 的技术,减少打包的体积——依赖于ES2015(ES6)的import和export模块语法,通过编译阶段的静态分析,找到没有引入的模块并打上标记,在打包时将这些被标记的模块忽略掉。这样也就间接达到了减少项目引入的 Vue.js 包体积的目的。

2、数据劫持优化

vue 的一大特色是它的数据是响应式的——DOM是数据的映射,数据变化后可以自动更新DOM。
实现“数据响应式”,必须劫持数据的访问和更新。
那么vue怎么知道更新哪一片DOM呢?
在渲染DOM的时候访问了数据,我们可以对它进行访问劫持,这样就在内部建立的依赖关系,也就知道对应的DOM是什么了。实际的实现要比这更复杂,内部依赖了一个watcher结构来管理这些依赖:
在这里插入图片描述
vue2.x 通过 Object.defineProperty 这个API劫持数据的getter和setter:

Object.defineProperty(data, 'a', {
	get() {},
	set(){}
})

但这个API有些缺陷:

  • 它必须先知道要拦截的key是什么,所以它并不能检测对象属性的添加和删除。vue2.x 为了解决这个问题增加了 $set 和 $delete 的实例方法,这无疑给使用者增加了额外的心智负担。
  • 如果我们定义的数据过于复杂,就会有相当大的性能负担。这是因为:vue 无法判断你在运行时到底要访问哪个属性,所以对于一个嵌套层级较深的对象,如果要劫持到它内部深层次的对象的变化,就需要递归便利这个对象,执行 Object.defineProperty 把每一层对象都变成响应式的对象的。

为了解决上述两个问题,vue3.x 采用了 Proxy API来做数据劫持:

const observed = new Proxy(data, {
	get() {},
	set(){}
})

由于它劫持的是整个对象,所以自然对整个对象的删除和增加都能检测到。
但是,Proxy API并不能监听到内部深层次的对象的变化。因此,vue3.x 采用了在 getter 中去递归响应式。这样的好处是,真正访问到的内部对象才会变成响应式,而不是无脑递归。这无疑大大提升了性能。

3、编译优化

下图是 vue2.x 从创建 vue 实例开始到渲染成 DOM 的过程:
在这里插入图片描述
上面说过的响应式就是发生在图中的 init 阶段。
另外,“template compiled to render function” 的流程可以借助 view-loader 在 webpack 编译阶段离线完成,并非一定要在运行时完成。所以想要优化整个vue.js的运行时,除了数据部分的优化,还可以在耗时较多的patch阶段想办法。于是,vue3.x 在编译阶段优化了编译的结果,来实现了运行时 patch 阶段的优化。

(1)、编译粒度的优化

vue2.x 的数据更新并触发重新渲染的粒度是组件级的:
在这里插入图片描述
虽然,vue2.x 能保证触发更新的组件最小化,但是单个组件内部依然需要遍历该组件的整个 v-node 树,比如我们要更新以下组件:

<template>
<div id="content">
	<p>1</p>
	<p>2</p>
	<p>{{number}}</p>
	<p>4</p>
	<p>5</p>
</div>
</template>

一个div中有5个p标签,只有第3个p标签是动态数据number,整个diff过程如图所示:
在这里插入图片描述
可以看到,因为这段代码只有一个动态节点, 所以这里有很多的diff和遍历都是不需要的。这就导致 v-node 的性能和模板大小正相关,跟动态节点数量无关。当一些组件整个模板只有少量动态节点时,这些便利都是性能的浪费,理想状态只需要diff这个绑定number的p标签即可。vue.3.x 做到了。

vue.3.x 通过编译阶段对静态模板的分析,编译生成了 block tree:

  • block tree 是一个模板基于动态节点指令切割的嵌套区块,每个区块内部节点结构是固定的。
  • block tree 的每个区块只需要以一个Array来追踪自身包含的动态节点。

借助 block tree,vue.js 将 v-node 更新性能由与模板整体大小正相关提升为与动态内容的数量相关。这是一个非常大的性能突破。

除此之外,vue3.x 在编译阶段还做了:slot编译优化、事件侦听函数的缓存优化、运行时重写diff算法,这些之后会说。

三、语法 API 的优化

vue3.x 推出了 Composition API 。

Composition API 相较于 Options API 的优势:

  • Composition API 优化了编码的逻辑组织——将某个逻辑关注点的相关代码全部放在一个函数里。
  • Composition API 优化了代码的逻辑复用——使用 hooks 取代了 mixin。

1、优化了编码的逻辑组织

相较于 Options API,Composition API 优化了编码的逻辑组织。

Options API 的好处是写法非常符合人的逻辑思维,对新手比较友好——Options API 的设计是按照 method、computed、data、props 这些不同的选项分类的。当组件小的时候这种分类方式一目了然,但是在大型组件中,一个组件可能有多个逻辑关注点,当使用 Options API 的时候,每个关注点都有自己的 options,如果需要修改一个逻辑的关注点,就需要在单个文件中不断的上下切换寻找。

Composition API 解决了这个问题,就是将某个逻辑关注点相关的代码全部放到一个函数里,这样当需要修改一个功能时就不需要在文件中跳来跳去了。
在这里插入图片描述

2、优化了代码的逻辑复用

在 vue2.x 的 Options API 中,可以使用 mixin 来做代码的逻辑复用。使用单个 mixin 的问题不大,但是当我们的组件混入大量不同的 mixin 的时候,会存在两个非常明显的问题:

  • 命名冲突:每个 mixin 都可以定义自己的 props、data,他们之间是无感的,所以很容易定义相同的变量名,导致命名冲突。
  • 数据来源不清晰:对组件而言,如果模板中使用不在当前组件中定义的变量,那么就不会太容易知道这些变量在哪里定义的,这就是数据来源不清晰。

mixin 的以上问题在 Composition API 中均得到了解决——定义 hook 函数,在组件中使用 hook 函数。

Composition API 除了在逻辑复用方面有优势,还有更好的类型支持。因为他们都是一些函数,在调用函数时,自然所有的类型都被推导出来了。不像 Options API 所有的东西都使用 this。

另外,Composition API 对 tree-shaking 友好,代码也更容易压缩。

虽然 Composition API 有诸多优势,它也有一定的缺陷,之后再说。

关于 Composition API 的具体实现和设计原理,也在之后说。




【参考资源】
vue3.x 的源码 github 地址
vue3 源码解析教程
全网最详细 Vue3 源码解析

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/261034.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Java学习系列(四)

1.Scanner类 java.util.Scanner 是 Java5 的新特征&#xff0c;我们可以通过 Scanner 类来获取用户的输入。 import java.util.Scanner; public class ScannerDemo {public static void main(String[] args) {Scanner scan new Scanner(System.in);// 从键盘接收数据// next…

css学习笔记2

css学习笔记2 CSS三大特性1.三大特性1.1层叠性1.2继承性1.3优先级 2.颜色的表示2.1表示方式一&#xff1a;颜色名2.2表示方式二&#xff1a;rgb或rgba2.3表示方式三&#xff1a;HEX或HEXA2.4表示方式四&#xff1a;HSL或HSLA CSS三大特性 1.三大特性 1.1层叠性 概念&#xff…

SLAM算法与工程实践——SLAM基本库的安装与使用(6):g2o优化库(1)g2o库的安装

SLAM算法与工程实践系列文章 下面是SLAM算法与工程实践系列文章的总链接&#xff0c;本人发表这个系列的文章链接均收录于此 SLAM算法与工程实践系列文章链接 下面是专栏地址&#xff1a; SLAM算法与工程实践系列专栏 文章目录 SLAM算法与工程实践系列文章SLAM算法与工程实践…

如何提高React组件的渲染效率的?在React中如何避免不必要的render?

面试官&#xff1a;说说你是如何提高组件的渲染效率的&#xff1f;在React中如何避免不必要的render&#xff1f; 一、是什么 react 基于虚拟 DOM 和高效 Diff 算法的完美配合&#xff0c;实现了对 DOM 最小粒度的更新&#xff0c;大多数情况下&#xff0c;React 对 DOM 的渲染…

debian10安装配置vim+gtags

sudo apt install global gtags --version gtags //生成gtag gtags-cscope //查看gtags gtags与leaderf配合使用 参考: 【VIM】【LeaderF】【Gtags】打造全定制化的IDE开发环境&#xff01; - 知乎

Apache Superset如何实现无公网ip实时远程访问本地数据【内网穿透】

文章目录 前言1. 使用Docker部署Apache Superset1.1 第一步安装docker 、docker compose1.2 克隆superset代码到本地并使用docker compose启动 2. 安装cpolar内网穿透&#xff0c;实现公网访问3. 设置固定连接公网地址 前言 Superset是一款由中国知名科技公司开源的“现代化的…

生物信息学R分析工具包ggkegg的详细使用方法

ggkegg介绍 ggkegg 是一个用于生物信息学研究的工具&#xff0c;可以用于分析和解释基因组学数据&#xff0c;并将其与已知的KEGG数据库进行比较。ggkegg 是从 KEGG 获取信息并使用 ggplot2 和 ggraph 进行解析、分析和可视化的工具包&#xff0c;结合其他使用 KEGG 进行生物功…

HAproxy做七层代理+keepalived高可用,实现动静分离,由nginx处理静态页面,tomcat处理动态页面

目录 一、三种软负载均衡器的区别 关于三种负载均衡器的性能对比&#xff1a; 关于三种负载均衡器的代理类型对比&#xff1a; 关于三种负载均衡器的健康检查对比&#xff1a; 二、haproxy的8中负载均衡调度算法 haproxy的会话保持的方式 haproxy的配置文件学习 三、实操…

Python中导入Excel数据:全面解析与实践

目录 一、引言 二、选择合适的库 三、读取Excel文件 四、处理数据 五、错误处理和异常处理 1、使用try-except语句捕获和处理异常&#xff1a; 2、使用try-except语句捕获和处理特定异常类型&#xff1a; 六、性能优化 七、数据验证 1、检查缺失值&#xff1a; 2、检…

如何解决idea创建版本时只有Java21和Java17选项

idea如果版本高了就会出现在创建Springboot项目时只有Java21和Java17选项 选择jdk1.8的时候很可能出现下图报错&#xff0c;这是因为版本jdk1.8与Java17不兼容 解决办法一般有三种&#xff0c;这里列举两种 1、替换下载数据源 可以将https://start.spring.io/ 替换成 https:…

科普-电子合同签署,这三步不能忽视

关于电子合同&#xff0c;许多人认为我自己直接内部发送邮件/传真等发送电子版合同或者我自己创建一个电子合同平台&#xff0c;这种怎么不属于电子合同呢&#xff1f; 在这里给大家科普一个知识点&#xff1a;签电子合同&#xff0c;需要经过这“三个步骤”。 根据《电子签名…

31. 深度学习进阶 - 全连接层及网络结构

Hi&#xff0c;你好。我是茶桁。 之前的课程咱们学习了卷积以及池化&#xff0c;那到底卷积是如何构成卷积神经网络的呢&#xff1f;我们这节课来好好讲一下。 全连接层 整个卷积的运算就是经过卷积&#xff0c;再经过pooling&#xff0c;再经过卷积。会把这个图形变的很小。…

案例系列:营销模型_客户细分_无监督聚类

案例系列&#xff1a;营销模型_客户细分_无监督聚类 import numpy as np # 线性代数库 import pandas as pd # 数据处理库&#xff0c;CSV文件的输入输出&#xff08;例如pd.read_csv&#xff09;/kaggle/input/customer-personality-analysis/marketing_campaign.csv在这个项…

新型智慧视频监控系统:基于TSINGSEE青犀边缘计算AI视频识别技术的应用

边缘计算AI智能识别技术在视频监控领域的应用有很多。这项技术结合了边缘计算和人工智能技术&#xff0c;通过在摄像头或网关设备上运行AI算法&#xff0c;可以在现场实时处理和分析视频数据&#xff0c;从而实现智能识别和分析。目前来说&#xff0c;边缘计算AI视频智能技术可…

Rocky Linux 9.3 安装 Jenkins 2.426.2 (超级详细版本)

安装步骤 官网的安装文档 导入秘钥 sudo wget -O /etc/yum.repos.d/jenkins.repo \https://pkg.jenkins.io/redhat-stable/jenkins.repo sudo rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io-2023.key 更新yum源 sudo yum upgrade 安装JDK&#xff08;已…

回顾 2023 这一年的进展,哪些 AI 公司让你觉得未来可期?

文章目录 前言行业趋势1、Open AI 成立于 2015 年2、Tome 成立于 2020 年3、Synthesia 成立于 2017 年4、Uizard 成立于 2018 年5、Soundful 成立于 2019 年6、GoodVision 成立于 2017 年7、Writesonic 成立于 2021 年8、Atomic AI 成立于 2020 年9、Eightfold 成立于 2016 年1…

java SSM健身跑步爱好者社区系统myeclipse开发mysql数据库springMVC模式java编程计算机网页设计

一、源码特点 java SSM健身跑步爱好者社区系统是一套完善的web设计系统&#xff08;系统采用SSM框架进行设计开发&#xff0c;springspringMVCmybatis&#xff09;&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整 的源代码和数据库&#xff0c;系统…

Redis-学习笔记

Remote Dictionary Server(Redis) 是一个开源的使用 ANSI C 语言编写、遵守 BSD 协议、支持网络、可基于内存、分布式、可选持久性的键值对(Key-Value)存储数据库&#xff0c;并提供多种语言的 API&#xff0c;是跨平台的非关系型数据库。 Redis 通常被称为数据结构服务器&…

小程序时代,如何从零开始打造家居展示咨询平台

随着移动互联网的快速发展&#xff0c;小程序成为了各行各业推广和展示产品的新利器。对于家居展示咨询平台来说&#xff0c;打造一款精美实用的小程序不仅可以提升用户体验&#xff0c;还能够有效提高品牌形象和市场竞争力。下面就来介绍一下从零开始打造家居展示咨询平台的步…

字节跳动 Spark Shuffle 大规模云原生化演进实践

Spark 是字节跳动内部使用广泛的计算引擎&#xff0c;已广泛应用于各种大规模数据处理、机器学习和大数据场景。目前中国区域内每天的任务数已经超过 150 万&#xff0c;每天的 Shuffle 读写数据量超过 500 PB。同时某些单个任务的 Shuffle 数据能够达到数百 TB 级别。 与此同…