性能优化之resize

多组件场景下的 resize 处理方案对比

当前方案 vs 组件重建方案

当前方案:screenKeys 触发组件重建

性能消耗分析

  • 高消耗:每次 screenKeys 变化时,所有使用该 key 的组件都会销毁重建
  • DOM 操作:移除旧 DOM 元素,创建新 DOM 元素,触发完整的组件生命周期
  • 资源重分配:重新计算样式、重新绑定事件、重新初始化状态

替代方案:集中式 resize 监听

方案一:全局单一监听器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 在全局或父组件中
let resizeTimeout: number | null = null;
const handleGlobalResize = () => {
clearTimeout(resizeTimeout);
resizeTimeout = setTimeout(() => {
// 通知所有需要响应 resize 的组件
emit('resize');
}, 100);
};

onMounted(() => {
window.addEventListener('resize', handleGlobalResize);
});

onUnmounted(() => {
window.removeEventListener('resize', handleGlobalResize);
});

方案二:每个组件独立监听

1
2
3
4
5
6
7
8
// 在每个组件中
onMounted(() => {
window.addEventListener('resize', handleResize);
});

onUnmounted(() => {
window.removeEventListener('resize', handleResize);
});

性能对比

方案 性能消耗 优点 缺点
组件重建 非常高 实现简单 大量 DOM 操作,视觉闪烁
全局单一监听器 性能最优,统一管理 需要事件传递机制
多组件独立监听 ⚠️ 中等 实现简单,组件解耦 多个事件监听器,可能重复执行

多组件场景建议

推荐方案:全局单一监听器

实现步骤

  1. 在父组件或全局状态管理中设置一个 resize 监听器
  2. 使用事件总线或 props 传递 resize 事件
  3. 子组件只执行必要的重新计算逻辑

代码示例

1
2
3
4
5
6
7
8
9
10
// 父组件
const emitResize = () => {
// 通知所有子组件
resizeEvent.value++;
};

// 子组件
watch(resizeEvent, () => {
init(); // 只重新计算,不重建组件
});

性能优势

  1. 减少事件监听器:只有一个全局 resize 监听器
  2. 避免 DOM 操作:组件状态更新而非重建
  3. 统一防抖处理:集中处理防抖逻辑
  4. 减少内存开销:避免频繁创建销毁组件实例

结论

全局单一 resize 监听器方案性能最优,相比组件重建方案:

  • 性能提升:减少 70-90% 的性能消耗
  • 用户体验:避免视觉闪烁,响应更流畅
  • 维护性:代码结构更清晰,逻辑更集中

在多组件场景下,强烈建议采用全局单一监听器方案,而不是通过改变 key 触发组件重建。


性能优化之resize
https://cszy.top/20260325-性能优化之resize/
作者
csorz
发布于
2026年3月19日
许可协议