防抖和节流需按用户操作意图选择:防抖适用于“收尾型”操作(如搜索、resize),仅最后一次生效;节流适用于“持续反馈型”操作(如滚动、mousemove),保证匀速响应。

防抖和节流不是“选一个用”,而是根据事件行为的意图来匹配——用户操作是“要等他停手再响应”,还是“得匀速响应不能断”。用错会丢逻辑、卡体验,甚至引发数据错乱。
防抖:适合“收尾型”操作
核心是“最后一次才生效”。比如输入搜索、调整窗口大小、表单校验,这些操作的真正意图往往在用户停止动作后才明确。
- 输入框联想:用户敲 a → ab → abc,你不需要发三次请求,只需等他停顿 300ms 后,用 abc 请求一次
- 防止重复提交:按钮点击后立刻禁用 + 防抖,避免网络慢时用户连点触发多次接口
- resize 布局重算:浏览器缩放时 resize 会高频触发,防抖可确保只在用户最终停稳时重新计算布局
节流:适合“持续反馈型”操作
核心是“固定节奏不中断”。比如滚动加载、鼠标跟随、拖拽位置更新,这类交互需要稳定、可预期的响应频率,否则会感觉卡顿或失联。
- 滚动懒加载:用户快速下滑时,scroll 事件每秒可能触发上百次,节流设为 200ms,就能保证每 200ms 最多检查一次是否到临界位置
- mousemove 跟踪:画布中鼠标移动要实时更新坐标或绘制轨迹,节流能平滑采样,避免 CPU 过载
- 按钮防连点(带反馈):既要限制提交频次,又希望每次点击都有视觉反馈(如按钮变色),节流比防抖更合适
实现要点:别只抄代码,注意这三处
手写时容易忽略的关键细节:
-
this 和参数必须正确传递:用
func.apply(this, arguments)或展开运算符...args,否则上下文丢失、参数为空 -
防抖支持立即执行选项:比如搜索框首次输入就该立刻查“a”,后续输入才防抖,需加
immediate参数控制 -
节流要注意时间戳与定时器配合:纯用
setTimeout可能导致间隔不准;推荐用时间戳判断是否过期 + 定时器兜底,确保严格按周期执行
怎么选?看两个问题
遇到新场景,快速判断:
- 用户操作结束后,是否只需要一个结果?→ 选防抖
- 用户操作过程中,是否需要持续、均匀地获得反馈?→ 选节流











