引言滚动页面、输入搜索词、拖动窗口大小这些操作每秒可能触发几十上百次。如果每次触发都执行一段较重的逻辑页面就会卡顿、掉帧。解决思路不是让逻辑变快而是控制执行的频率。防抖和节流就是两种最常用的频率控制手段。这篇文章只讲这一个问题把两者的区别、原理和适用场景讲清楚。一、问题从哪来很多事件是高频触发的。滚动事件在滚动过程中持续触发输入事件每敲一个字符触发一次窗口缩放每改变一点像素就触发一次。如果每次触发都做完整处理比如重新计算布局、发起网络请求、遍历大数组主线程就会被占满渲染和交互都受影响。用户感觉就是卡。但很多处理其实不需要每次触发都做。搜索联想用户还在连续打字中间状态没必要请求滚动加载滚动过程中不需要每毫秒都判断窗口缩放等用户停下再调整布局更合理。所以需要一种机制把高频触发合并成低频执行。防抖和节流就是干这个的。二、防抖等停下来再执行防抖的思路是事件触发后不立刻执行而是设定一个等待时间。如果在这个时间内事件又触发了就重新计时。只有当事件停止触发、等待时间走完才真正执行一次。可以想象成电梯门有人进出就重新计时等没人进出了门才关上。防抖就是等安静下来再行动。适用场景搜索框输入联想、表单实时校验、窗口大小调整后的布局重算、按钮防止重复点击。这些场景的共同点是中间过程不重要只关心最终结果。注意点如果事件一直触发不停防抖会导致永远不执行。所以有些场景需要立即执行一次之后等停止再执行的变体。三、节流固定频率执行节流的思路是不管事件触发多频繁固定时间内最多执行一次。可以想象成水龙头滴水你开得再大它也是按固定节奏一滴一滴往下掉。节流就是按节奏来不跟着事件疯跑。适用场景滚动加载更多、拖拽时更新位置、鼠标移动时的提示、游戏里的按键响应。这些场景的共同点是需要持续响应但不能太频繁固定节奏就够了。注意点节流有首次执行和末次执行的区别。有的实现第一次触发立刻执行之后按间隔来有的等间隔到了才执行第一次。选择哪种取决于交互期望。四、两者的核心区别防抖是等停止事件连续触发时只在最后执行一次。执行时机取决于事件什么时候停。节流是按频率事件连续触发时按固定间隔执行多次。执行时机取决于时间间隔不取决于事件是否停止。打个比方防抖像等所有人都上车了再发车节流像每隔十分钟发一班车不管人多人少。选择哪种取决于你是关心最终状态还是过程中的持续反馈。五、常见误区误区一防抖节流混用。搜索联想用节流会导致用户还没打完就发请求浪费流量滚动加载用防抖会导致滚动过程中一直不加载停下来才加载体验不好。场景要匹配。误区二忘记取消。组件销毁或页面切换时防抖节流的定时器还在跑可能触发已经不需要的逻辑甚至报错。要在适当时机取消。误区三等待时间拍脑袋定。时间太短起不到控制频率的作用太长会让用户觉得反应迟钝。要根据交互特点调整通常输入类偏短滚动类偏中等。误区四在防抖节流里做重活。它们只控制频率不减少单次执行的开销。如果单次逻辑本身很重即使降低频率也可能卡。重活还是要拆分或放到后台线程。六、实际开发中的组合使用实际项目里防抖和节流经常组合使用。比如搜索联想用户输入时用防抖避免每敲一个字就请求请求返回后渲染结果时如果结果很多可以用节流控制渲染频率。再比如滚动加载滚动事件用节流控制检查频率检查到接近底部时再用防抖确保不会连续触发多次加载。理解两者的特性才能灵活组合而不是死记输入用防抖、滚动用节流。七、总结防抖和节流解决的是同一个问题高频事件太多需要控制执行频率。防抖等停止后执行一次节流按固定间隔执行多次。选择取决于你是关心最终结果还是持续反馈。理解原理、匹配场景、注意取消和耗时你就能让页面在高频交互下依然流畅。这是前端性能优化中最实用的一课。