源码结构上面的优化 采用了 monorepo 和 typscript
- vue2 的源码是托管 src 目录 下 根据功能才分了 compiler core platforms server sfc shared
- vue3 的源码 整体通过 monorepo 维护 不同的模块拆分到 packages 目录下 拆分到颗粒度更细 指责划分更明确 依赖关系也更明显 便于 开发人员 阅读和维护 提高了可维护性
- vue2 是用的 flow 进行 类型检查的 flow 在复杂场景下的支持不好
- vue3 是用的 typscript 重构的
源码体积的优化
-
移除一些不常用的 API filter inline-template delete set 等
-
引入tree-shaking,可以将无用模块“剪辑”,仅打包需要的,使打包的整体体积变小了
-
tree-shaking 的原理也很简单 依赖 es2015 模块语法的静态结构 import export 通过编译阶段的静态分析 找到没有 导入的模块 打上标记 在压缩阶段删除 未使用的模块
-
这样 vue3的体积是根据 项目中使用到的功能来变化的
数据劫持的优化
-
直接 Proxy 替换 Object.defineProperty
- 缺点: 兼容性更低
- vue2 使用的 Object.defineProperty 需要递归遍历 对象来达到劫持的深层次变化监听
- vue3 使用 proxy 实现了 增加删除都可以监听到 但是也无法深层次的监听对象的变化 但是是在 proxy 处理器的 getter 中递归响应 好处是: 真正访问到的内部对象才会变成响应式 vue2 是 无脑递归
编译优化
-
vue2 的更新 dom 颗粒度是到组件的 虽然保证了更新组件的最小化 但是单个组件内部 依然需要遍历整个 vnode
-
vue3 通过 编译阶段 对静态模版的分析 编译生成了 Block Tree
- Block Tree 是将模版基于 动态节点 指令切割的嵌套区块 每个区块内部的节点结构是固定的 每个区块用一个 Array 来追踪自身包含的 动态节点
-
vue3 将性能优化到 以 动态节点数量 相关 很大的性能突破
语法 API 优化
-
Compostion Api
- 更好的逻辑代码拆分 代码不分散
- 复用优势更大
-
Vue2 options
- 代码过于分散
- 多个 mixins 变量命名容易冲突
引入 RFC
- 保证每一个 fearure-request 都是经过团队讨论才会进行开发的
- 提升了 稳定性 少走弯路
diff算法优化
- 新增了静态标记 如果被标记过的 就不会在重新对比
- vue2 是全量对比
静态提升
- 会把静态节点进行局部作用域的提升 再次更新的时候不会循环 会直接取声明的
- vue2 是 无论是否更新 都会重新创建 dom节点然后渲染
cacheHandles 事件监听缓存
- cacheHandlers 是Vue3中提供的事件缓存对象,当 cacheHandlers 开启,会自动生成一个内联函数,同时生成一个静态节点。当事件再次触发时,只需从缓存中调用即可,无需再次更新
- vue2.x中,绑定事件每次触发都要重新生成全新的function去更新,
SSR优化
- 当存在大量静态内容时,这些内容会被当作纯字符串推进一个 buffer 里面,即使存在动态的绑定,会通过模版插值潜入进去。这样会比通过虚拟 dmo 来渲染的快上很多。
- 当静态内容大到一个量级的时候,会用_createStaticVNode 方法在客户端去生成一个 static node,这些静态 node,会被直接 innerHtml,就不需要再创建对象,然后根据对象渲染。