网站建设对企业的要求,网站建设分销协议,wordpress 全局设定,餐厅网站模版目录 前言一、源码优化1、vue3.x 采用 monorep 的理念来管理源码2、vue3.x 源码采用 TypeScript 开发 二、性能优化1、减少源码的体积2、数据劫持优化3、编译优化#xff08;1#xff09;、编译粒度的优化 三、语法 API 的优化1、优化了编码的逻辑组织2、优化了代码的逻辑复用… 目录 前言一、源码优化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 的技术减少打包的体积——依赖于ES2015ES6的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 idcontentp1/pp2/pp{{number}}/pp4/pp5/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 treevue.js 将 v-node 更新性能由与模板整体大小正相关提升为与动态内容的数量相关。这是一个非常大的性能突破。
除此之外vue3.x 在编译阶段还做了slot编译优化、事件侦听函数的缓存优化、运行时重写diff算法这些之后会说。
三、语法 API 的优化
vue3.x 推出了 Composition API 。
Composition API 相较于 Options API 的优势
Composition API 优化了编码的逻辑组织——将某个逻辑关注点的相关代码全部放在一个函数里。Composition API 优化了代码的逻辑复用——使用 hooks 取代了 mixin。
1、优化了编码的逻辑组织
相较于 Options APIComposition 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 源码解析