防抖节流
防抖:在用户输入搜索框时,频繁触发输入事件,如果每次输入都立即发送请求,可能会导致性能问题。防抖就是在事件被触发后,等待一定时间再执行回调,如果在这段时间内再次触发事件,则重新计时。这样可以确保只在用户停止输入后才执行操作,减少不必要的请求。
节流:在滚动事件或者窗口调整时,限制回调的执行频率。比如,即使用户不断滚动页面,每隔一定时间才执行一次回调,避免过于频繁的执行影响性能。节流的核心是保证在一定时间内只执行一次回调。
防抖(Debounce)和节流(Throttle)是 JavaScript 中优化高频事件处理的核心技术,二者目标都是减少函数执行频率,但实现逻辑不同。
防抖(Debounce)
目标:事件触发后,等待一段时间再执行回调。若在等待期间事件再次触发,则重新计时。
电梯关门场景——最后一个人进入后,等待一段时间才关门。
javascript
function debounce(func, delay) {
let timer = null;
return function(...args) {
clearTimeout(timer); // 清除旧定时器
timer = setTimeout(() => {
func.apply(this, args); // 延迟执行
}, delay);
};
}
// 使用示例(输入框搜索建议)
const searchInput = document.getElementById('search');
searchInput.addEventListener('input', debounce(function(e) {
console.log('发送搜索请求:', e.target.value);
}, 500));
function debounce(func, delay) {
let timer = null;
return function(...args) {
clearTimeout(timer); // 清除旧定时器
timer = setTimeout(() => {
func.apply(this, args); // 延迟执行
}, delay);
};
}
// 使用示例(输入框搜索建议)
const searchInput = document.getElementById('search');
searchInput.addEventListener('input', debounce(function(e) {
console.log('发送搜索请求:', e.target.value);
}, 500));
应用场景:
- 输入框实时搜索(避免频繁请求)
- 窗口大小调整(调整结束后计算布局)
- 按钮防重复点击(避免多次提交)
节流(Throttle)
目标:固定时间间隔内,只执行一次回调,稀释事件触发频率。
地铁发车——无论多少人进站,每 5 分钟发一班车。
javascript
function throttle(func, interval) {
let lastTime = 0;
return function(...args) {
const now = Date.now();
if (now - lastTime >= interval) { // 时间间隔检查
func.apply(this, args);
lastTime = now;
}
};
}
// 使用示例(滚动事件加载更多)
window.addEventListener('scroll', throttle(function() {
console.log('检查滚动位置,加载数据');
}, 1000));
function throttle(func, interval) {
let lastTime = 0;
return function(...args) {
const now = Date.now();
if (now - lastTime >= interval) { // 时间间隔检查
func.apply(this, args);
lastTime = now;
}
};
}
// 使用示例(滚动事件加载更多)
window.addEventListener('scroll', throttle(function() {
console.log('检查滚动位置,加载数据');
}, 1000));
应用场景:
- 页面滚动加载(避免频繁触发计算)
- 鼠标移动事件(如拖拽元素)
- 游戏中的按键操作(限制技能冷却时间)
防抖 vs 节流对比
特性 | 防抖(Debounce) | 节流(Throttle) |
---|---|---|
执行时机 | 事件停止触发后执行 | 固定时间间隔执行 |
适用场景 | 关注最终状态(如搜索输入完成) | 关注过程状态(如滚动位置) |
极端情况 | 高频触发可能导致永不执行 | 保证最低执行频率 |
代码核心 | clearTimeout + setTimeout | 时间戳差值判断 |
注意
- 合理设置时间参数:防抖延迟(如 300ms)、节流间隔(如 1s)需结合实际场景。
- 避免内存泄漏:在组件卸载时(如 React/Vue)清除定时器。
- 结合 requestAnimationFrame:对动画类高频事件,用 requestAnimationFrame 实现节流更流畅。