防抖和节流是解决高频事件引发卡顿、重复请求等问题的实用技术:防抖在操作停止后执行一次,适用于搜索、校验等终态场景;节流按固定间隔执行,适用于滚动、拖拽等连续过程场景。

JavaScript 防抖(Debounce)和节流(Throttle)不是为了“炫技”,而是为了解决高频事件触发带来的实际问题——比如页面卡顿、重复请求、资源浪费和交互失真。它们通过控制函数执行频率,让前端响应更合理、更轻量、更贴近用户真实意图。
防抖:等用户“停下来”再响应
防抖适用于那些只需在操作结束后执行一次的场景。比如搜索框输入、窗口大小调整、表单校验。它的核心逻辑是:每次触发都重置计时器,只有连续触发完全停止后,才执行函数。
- 用户快速输入“react”5个字母,没防抖可能发5次请求;加了300ms防抖,只在最后停顿后发1次
- 适合“最终意图明确”的操作,如搜索、保存草稿、离开输入框前校验
- 实现简单:用 setTimeout + clearTimeout 即可,注意保存定时器ID避免内存泄漏
节流:固定节奏“匀速响应”
节流适用于需要持续反馈但又不能太频繁的场景,比如滚动加载、鼠标拖拽、游戏帧更新。它保证函数在指定时间间隔内最多执行一次,像节拍器一样稳定输出。
- 用户快速滚动页面1秒内触发100次 scroll 事件,节流设为100ms,就只执行约10次
- 适合“过程需要感知”的交互,如滚动定位、实时位置上报、canvas动画同步
- 常见实现有定时器版(较稳妥)和时间戳版(更精准),优先选前者避免累积延迟
不加控制的真实代价
看似只是“多跑几次函数”,实际影响层层递进:
立即学习“Java免费学习笔记(深入)”;
- 渲染层:频繁 setState 或 DOM 操作引发重排重绘,页面掉帧、卡顿明显
- 网络层:重复发送请求可能触发接口限流、增加服务器压力、甚至导致数据错乱(如连点提交)
- 用户层:输入延迟、按钮无响应、滚动跳动——这些“小问题”直接削弱信任感
怎么选?看用户是否在“持续表达”
一个朴素判断法:
- 用户动作有明确“结束点” → 选防抖(输入搜索、调整窗口)
- 用户动作本身是“连续过程” → 选节流(滚动、拖拽、鼠标移动)
- 不确定时,先上防抖;发现反馈太滞后(比如拖拽卡顿),再换节流
基本上就这些。不复杂但容易忽略,加几行代码,就能让页面从“能用”变成“好用”。










