Skip to content

vue3 的变化与优化

前端框架的通用价值(不论 vue 还是 react)

  • 框架的优点
  • html 不灵活,需要反复复制
  • css 和 javascript 命名重复冲突
  • html 和 js 强耦合
  • 数据不同步

vue 的基本特征

  • 大致特点
  • 渐进式
  • 模板语法
  • 数据和视图同步
  • 组件化与独立组件

vue2 老问题与 vue3 新目标

代码架构

  • 所以迁移到 typescript,自动生成类型声明
  • 重新设计内部模块的分层
  • 为长期维护打好基础

性能优化空间

  • 编译器性能一般
  • 所以重写 v-dom 的算法
  • 结合编译器对 v-dom 进行优化
  • 优化组件实例化的开销

api 在大型项目中的可维护性

  • 选项式 api 在大项目中举步维艰
  • 引入对重构,复用和类型推导更友好的组合式 api

浏览器版本限制

  • vue2 支持 ie9,现在 没必要了
  • 现在支持最低 es2015

vue3 新特性(也基本是新优化)

数据劫持优化

  • object.defineProperty 需要预先确定拦截的 key/属性
  • 嵌套复杂的多层对象就需要递归调用 defineproperty,性能负担大
  • vue3 用 proxy,劫持整个对象,无所谓属性
  • 但也不能监听深层对象,需要显示指定递归调用
  • object.defineProperty 的 get 和 set
    • 处理数组是重写方法
  • proxy - 对数组更友好,且能监听到数组属性

编译优化

  • new vue -> init() -> $mount -> compile -> render() -> vnode -> patch -> DOM

  • vue 的更新颗粒度是组件级别的,但很多时候我们只需要更新一个组件内的少数响应性数据,但原有的 vue2 内部依然需要循环和递归遍历 vnode 树来保证大家都更新了。但理想状态下,diff 应该能明确指向确实需要响应式变化的具体标签,其他就不用变

  • vue3 搞出了 block tree,能让 vnode 更新从遍历整个模板变为只和动态变化内容相关

    • block tree 是一个将模板基于动态节点(有响应式变化的标签)指令切割的嵌套区块,每个区块内部的节点结构固定
    • 每个区块只需要一个 array 来追踪自身包含的动态节点
  • 运行时 diff 算法重写

    • v-dom 性能优化
    • 从处理后的源码看,主要是对响应式的内容打 path flag 标记,准备更新
    • 而且 flag 都用位运算
  • slot 优化

  • 事件监听函数的缓存优化

性能优化

  • 源码体积

  • 移除部分无用 api,inline,filter,

  • 引入 tree-shaking

  • tree-shaking

  • 编译阶段的静态分析就能找出没用到的模块并打标记

源码优化

  • monorepo 管理文件

  • ts 开发源码

  • 目的是提高代码的维护性和可开发性

  • monorepo 代码管理

  • 将模块拆分到不同 package 中,每个 packages 均有各自的 api,类型定义和测试

  • 使得整体模块划分更为细致,职责更清晰,依赖关系也更明显

  • 读起来,写起来,改起来更方便

  • ts 开发

  • 类型检查

  • 类型定义和 ide 提示

语法优化

  • composition api
  • options api 是一个“一个对象,包含了描述组件属性的选项”
  • 逻辑复用从 mixin 变为 composition,命名冲突和来源不清晰 重写双向数据绑定

API

  • 加入 fragments
    • 可以写多个根节点,不像 vue2 只能写一个包住其他
    • 实现方式是加虚拟节点,这些节点并不会渲染
  • 支持 jsx 和 tsx
  • 支持 suspense teleport 组件以及多 v-model 用法