核心思路是减少 vue 响应式系统需追踪的依赖数量与深度:扁平化数据结构、用 id 映射替代嵌套数组、按需启用 reactive(shallowref/markraw)、模块化懒加载状态并及时卸载。

核心思路是减少 Vue 响应式系统需要追踪和更新的依赖数量与深度。数据结构越扁平、越精简,Vue 的依赖收集、变更通知和视图更新开销就越小。
把嵌套对象打平,避免深层响应式追踪
Vue 对深层嵌套对象(如 user.profile.address.city)做响应式处理时,会为每一层属性创建代理和依赖关系。层级越深,初始化和更新成本越高。
- ❌ 避免:用多层嵌套对象存业务数据,例如:
state = { user: { info: { name: '', settings: { theme: '' } } } } - ✅ 推荐:拆成一级键值对,用语义化前缀区分:
state = { userName: '', userTheme: '', userSettings: { /* 非响应式或按需 reactive */ } } - 若必须保留结构,可用
shallowRef或markRaw包裹不需要响应式的子树
用数组 ID 映射代替嵌套数组,降低列表更新复杂度
v-for 渲染大型列表时,若每个项都是深度 reactive 对象,每次 push、splice 或属性修改都会触发大量依赖通知。
递归分析 Vue 项目组件依赖,从入口文件生成组件层级图,支持 Vue 2/3,输出组件名、文件路径和属性。适用于分析组件结构、排查依赖或了解项目架构。
- ❌ 避免:直接存储完整对象数组:
messages: reactive([{ id: 1, sender: {}, content: '…', meta: { read: true } }]) - ✅ 推荐:分离“索引”与“实体”,用 Map 或对象字面量缓存详情:
messageIds: ref([1, 2, 3])messageMap: shallowRef({ 1: { content: '…', read: true }, 2: { … } }) - 这样新增/删除 ID 不触发整个 messageMap 响应式更新;仅读取单条消息时才访问对应 key,减少无效依赖
区分响应式与非响应式字段,按需启用 reactive
不是所有数据都需要实时驱动视图。静态配置、缓存快照、第三方库实例等,加入响应式只会徒增开销。
- 用
shallowRef替代ref存储大型数组或对象(只监听 .value 赋值,不代理内部) - 用
markRaw标记无需响应式的对象,例如:const config = markRaw({ API_BASE: '/api', FEATURES: { chat: true } }) - 在 Vuex/Pinia 模块中,将计算逻辑移入 getter / computed,state 中只存原始字段,避免冗余派生数据占内存
模块化 + 懒加载状态,控制响应式范围
全局 store 中堆积大量未使用模块的状态,会让 Vue 持续维护无关依赖。
- 将功能域拆分为独立 Vuex/Pinia 模块,按路由或功能动态注册(
store.registerModule('analytics', module, { preserveState: false })) - 非首屏模块(如报表页、设置页)的状态延迟初始化,避免启动时一次性构建全部响应式结构
- 组件卸载时,主动调用
unregisterModule或清空局部状态,释放 watcher 和 proxy 内存
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!









