resize事件适合节流而非防抖,因其需在调整过程中阶段性响应(如实时缩放画布、切换导航栏),节流能保证每100–200ms执行一次,兼顾反馈及时性与性能。

窗口调整大小(resize)事件在用户拖拽浏览器边框时会高频触发,可能每秒几十甚至上百次。若直接在监听函数中执行 DOM 重排、样式计算或重新渲染等操作,极易引发页面卡顿。节流的核心是“固定时间间隔内最多执行一次”,比防抖更适用于需要持续响应但又不能过载的场景——比如实时适配布局、更新图表尺寸、同步侧边栏高度等。
为什么 resize 适合用节流而不是防抖
防抖会在用户停止调整后才执行,适合搜索建议、表单校验这类“等稳定再处理”的逻辑;而 resize 常需在调整过程中就阶段性反馈,例如: - 拖拽过程中实时缩放画布 - 动态切换移动端/桌面端导航栏状态 - 滚动容器内嵌组件的尺寸同步 节流能保证每 100–200ms 至少执行一次,既控制频率,又不丢失关键中间状态。
用时间戳法实现轻量节流
这是最常用、无副作用的实现方式,适合 resize 这类无须立即首次执行的场景:
function throttle(func, delay) {
let lastTime = 0;
return function(...args) {
const now = Date.now();
if (now - lastTime >= delay) {
func.apply(this, args);
lastTime = now;
}
};
}
<p>window.addEventListener('resize', throttle(() => {
updateLayout(); // 你的布局更新逻辑
}, 160)); // 约每秒6次,兼顾流畅与性能
- 160ms 是较稳妥的起点(对应约6FPS),对视觉反馈足够,又大幅降低调用频次
- 不依赖定时器,无内存泄漏风险,this 和事件参数自动保留
- 避免使用
setTimeout版本,因 resize 触发密集时易堆积未清除的定时器
实际使用中的关键注意点
节流不是“加了就完事”,需结合具体逻辑调整:
-
避免在节流函数内做重计算:如反复调用
getBoundingClientRect()或遍历大量 DOM 节点,应提取为缓存值或延迟到requestAnimationFrame中执行 - 区分是否需要首次立即执行:若需在 resize 开始时立刻响应(如初始化断点状态),改用带 leading 参数的节流版本,或单独调用一次初始化函数
- 移除监听器时无需特殊清理:纯时间戳实现无定时器引用,不会造成内存泄漏;但若用第三方库(如 Lodash),记得保存返回函数以便 later 移除
- 现代替代方案可考虑 ResizeObserver:对特定元素尺寸变化监听更精准、性能更好,但不替代 window.resize 全局监听



















