防抖与节流函数
2025/1/10大约 3 分钟
防抖(Debounce) 和 节流(Throttle) 是 JavaScript 中用于优化高频事件处理的两种技术 它们的主要目的是减少事件触发的频率,从而提升性能
| 特性 | 防抖(Debounce) | 节流(Throttle) |
|---|---|---|
| 触发时机 | 事件停止触发后,延迟 delay 后执行 | 每隔 interval 时间执行一次 |
| 执行次数 | 事件停止后只执行一次 | 在持续触发时,周期性执行 |
| 适用场景 | 搜索框输入联想、窗口大小调整 | 滚动事件、按钮防连点 |
| 极端情况 | 若事件持续触发,函数永不执行 | 即使事件持续触发,函数按固定间隔执行 |
防抖函数
事件触发后,等待一段时间
delay,若期间没有再次触发事件,则执行函数;若期间事件被重复触发,则重新计时 核心目标:确保高频事件的最终状态触发一次操作。
适用场景:
- 输入框实时搜索(等待用户停止输入后再发送请求)
- 窗口大小调整(等待用户停止调整后再计算布局)
// 防抖函数
function debounce(func, delay) {
let timeoutId;
return function (...args) {
const context = this;
clearTimeout(timeoutId); // 取消之前的延迟调用
timeoutId = setTimeout(() => {
func.apply(context, args); // 延迟结束后执行
}, delay);
};
}
// 使用示例:输入框搜索联想
const searchInput = document.getElementById('search');
const handleSearch = () => console.log('发起搜索请求');
const debouncedSearch = debounce(handleSearch, 500);
searchInput.addEventListener('input', debouncedSearch);节流函数
无论事件触发多频繁,在固定时间间隔
interval内,最多执行一次函数 核心目标:稀释高频事件的触发频率,确保周期性执行(如滚动)
适用场景:
- 滚动事件(每隔一段时间执行一次处理函数)
- 按钮点击(防止用户快速多次点击)
// 节流函数(时间戳实现)
function throttle(func, interval) {
let lastTime = 0;
return function (...args) {
const now = Date.now();
if (now - lastTime >= interval) {
func.apply(this, args);
lastTime = now; // 更新最后执行时间
}
};
}
// 节流函数(定时器实现)
function throttle(func, interval) {
let timeoutId;
return function (...args) {
const context = this;
if (!timeoutId) {
timeoutId = setTimeout(() => {
func.apply(context, args);
timeoutId = null; // 执行后重置定时器
}, interval);
}
};
}
// 使用示例:滚动事件处理
const handleScroll = () => console.log('处理滚动');
const throttledScroll = throttle(handleScroll, 300);
window.addEventListener('scroll', throttledScroll);关键场景对比
输入框搜索
- 使用防抖:用户停止输入 500ms 后,才发起搜索请求,避免每输入一个字符都请求
- 若用节流:用户输入时会每隔 500ms 请求一次,可能导致无效请求
无限滚动加载
- 使用节流:用户滚动时每隔 300ms 检查一次是否触底,避免频繁计算
- 若用防抖:用户停止滚动后才触发,可能错过中间滚动过程中的触底时机
总结
- 防抖:关注最终状态,避免中间过程重复操作(如搜索、提交)
- 节流:关注事件的均匀执行(如滚动时定期更新位置)
根据具体场景选择合适的技术,能有效提升性能和用户体验