防抖(Debounce) 和 节流(Throttle) 是前端开发中常用的两种高频事件优化技术,它们的核心目标都是减少不必要的计算或请求,但实现方式和适用场景有所不同。
防抖(Debounce)
理解
防抖,顾名思义是防止抖动的意思,是一种控制高频事件触发频率的技术,它的核心思想是:在事件被频繁触发时,只有最后一次操作真正生效。简单来说,就是让一个动作“忍一忍”,等用户“停下来”后再执行。
用比喻的理解就是每当公交车司机等待乘客上车,当最后一名乘客上车后,司机会等待几秒,若无新乘客,便关门发车,若此时又有新的乘客过来,则司机的等待时间刷新,在该乘客上车后再等待几秒才发车。
应用场景
1.搜索框输入:用户每次输入并不都会触发关键词搜索,只有当用户停止输入时间至设定好的延迟时间(如500ms)时,才会触发关键词搜索。
2.窗口尺寸调整:在用户调整浏览器窗口大小时,通常会触发许多resize事件,使用防抖可以控制事件触发频率,优化性能。
3.按钮点击:如果有一个按钮需要执行某些操作,但用户可能会频繁点击,可以使用防抖来限制操作频次,避免重复执行。
实现原理
- 设置一个计时器(比如500ms)。
- 每次事件触发时 → 清除之前的计时器,重新开始倒计时。
- 倒计时结束后 → 执行目标操作。
本质:通过“重置倒计时”过滤掉高频的无效操作,确保只响应最后一次。
节流(Throttle)
理解
节流(Throttle)是一种控制高频事件触发频率的技术,核心思想是:在一定时间间隔内,只允许执行一次事件。简单来说,就是在连续触发事件时,固定时间内只执行一次动作,其他的事件触发会被忽略或延迟。
比喻地理解,节流就像是在一个车站,每次只有一辆公交车可以出发,即使站内有多个乘客准备乘车,也只能等待下一辆车到达(即下一次事件触发的时间到来)。这样可以防止公交车过于频繁的发车,避免交通拥堵。
应用场景
- 滚动监听:例如在网页滚动时触发某些操作(如懒加载图片、加载新内容等),可以通过节流技术控制滚动事件的频率,避免在滚动过程中频繁触发事件,从而减少计算和渲染压力。
- 按钮点击:用户可能会多次快速点击按钮,如果每次点击都触发请求,可能会导致重复操作或性能瓶颈。使用节流可以确保按钮在设定时间内只响应第一次点击。
- 实时数据更新:在一些实时数据场景中,尤其是与服务端交互时,频繁的请求可能带来服务器负载问题,使用节流技术可以限制请求频率,避免请求过于频繁。
- 表单提交:当用户不断提交表单时,可以使用节流限制提交请求的频率,确保表单不会被连续提交多次。
实现原理
-
设置一个时间间隔(如1000ms)。
-
每次事件触发时 → 判断距离上次事件触发的时间是否超过设定的时间间隔。
- 如果超过了时间间隔 → 执行目标操作并记录当前时间。
- 如果没有超过 → 忽略此次事件,直到时间间隔结束后才会触发下次执行。
本质:通过“固定时间间隔”来限制事件触发频率,确保在一定时间内只执行一次操作。
防抖和节流的区别
1. 核心区别
| 特性 | 防抖(Debounce) | 节流(Throttle) |
|---|---|---|
| 触发时机 | 事件停止触发后,延迟执行最后一次操作。 | 事件触发后,按固定间隔执行一次操作。 |
| 执行次数 | 只执行最后一次触发的操作。 | 按固定频率执行操作(可能漏掉中间操作)。 |
| 适用场景 | 关注“最终结果”的场景(如搜索输入)。 | 关注“过程”的场景(如滚动事件)。 |
| 比喻 | 司机等人(乘客全部上车才出发)。 | 地铁发车(每隔2分钟发一班,不等乘客)。 |
2.实际代码示例
防抖
function debounce(func, delay) {
let timer;
return function(...args) {
clearTimeout(timer);
timer = setTimeout(() => func.apply(this, args), delay);
};
}
// 输入框搜索防抖(停止输入500ms后执行)
input.addEventListener('input', debounce(search, 500));
节流
function throttle(func, interval) {
let lastTime = 0;
return function(...args) {
const now = Date.now();
if (now - lastTime >= interval) {
func.apply(this, args);
lastTime = now;
}
};
}
// 滚动事件节流(每200ms执行一次)
window.addEventListener('scroll', throttle(handleScroll, 200));
3. 适用场景对比
| 场景 | 防抖 | 节流 |
|---|---|---|
| 搜索框输入联想 | ✅ 用户停止输入后搜索 | ❌ |
| 窗口调整(resize事件) | ❌ | ✅ 固定间隔更新布局 |
| 按钮防重复点击 | ✅ 最后一次点击生效 | ❌ |
| 页面滚动加载更多 | ❌ | ✅ 滚动时定期检查位置 |
| 鼠标移动事件(mousemove) | ❌ | ✅ 限制触发频率 |
总结
防抖:关注结果,确保高频事件停止后才执行。
节流:关注过程,按固定频率执行。
根据实际需求选择合适的技术,甚至可组合使用(如先防抖再节流)。
希望本文能够加深你对防抖和节流的认识。