1. 响应式原理与Proxy优化
Vue3的响应式系统如何通过Proxy实现?对比Vue2的Object.defineProperty
有何性能优势?
-
Proxy优势:
- 直接监听整个对象而非逐个属性,支持动态新增/删除属性的响应式监听;
- 避免Vue2递归遍历深层对象导致的初始化性能损耗。
-
更新触发场景:
obj.a = { b: 3 }
触发1次更新(整个a
对象被替换);obj.a.b = 4
触发1次更新(Proxy直接追踪深层属性变化)。
2. 虚拟DOM优化策略
解释静态提升(Static Hoisting)和补丁标记(Patch Flags)的作用。
- 静态提升:将静态节点(如纯文本)编译为常量,避免重复创建VNode;
- 补丁标记 :在动态节点上标记变更类型(如
TEXT
/CLASS
),减少diff遍历范围。 - 模板示例:
css
<div>静态文本</div>
<div :class="{ active: isActive }">{{ dynamicText }}</div>
编译后静态节点仅生成一次,动态节点通过PatchFlag: 1
(文本变更)标记。
3. 性能优化实践
如何优化大型SPA的首屏加载速度?
- 异步组件+Suspense:
ini
const AsyncComponent = defineAsyncComponent(() => import('./HeavyComponent.vue'));
- 骨架屏占位 :结合
<Suspense>
的#fallback
插槽展示加载动画; - Vite代码分割 :配置
build.rollupOptions.output.manualChunks
拆分第三方库。
4. 编译时Block Tree优化
Vue3如何通过Block Tree减少动态节点遍历?
-
动态区块标记 :将模板中的
v-if
/v-for
编译为嵌套的Block节点,仅追踪动态子节点; -
**
v-if
与v-show
差异**:v-if
生成条件Block,动态切换子树;v-show
编译为display: none
样式,无Block结构。
5. Teleport与Suspense的协同问题
当<Teleport>
嵌套在<Suspense>
组件内时,如何处理异步加载内容的DOM层级问题?如何避免z-index
冲突?
- DOM层级控制:
xml
<Suspense>
<Teleport to="body"> <!-- 将内容传送到body层级 -->
<AsyncComponent />
</Teleport>
<template #fallback>
<div class="loading">Loading...</div> <!-- 骨架屏保留在组件树内 -->
</template>
</Suspense>
CSS解决方案:
css
/* 为Teleport内容添加作用域标识 */
.teleport-content {
position: relative;
z-index: 1000; /* 确保高于其他内容 */
isolation: isolate; /* 创建新的层叠上下文 */
}