防抖(Debounce)和节流(Throttle)是优化高频事件处理的两种常用技术,它们的核心目的是减少不必要的函数执行次数,提升性能。
1. 防抖(Debounce)
核心思想:事件触发后,等待一段时间内不再触发事件,才执行函数。如果在这段时间内再次触发,则重新计时。
适用场景:搜索框输入联想、窗口大小调整(resize)、文本编辑器保存。
实现代码:
function debounce(func, wait, immediate = false) {
let timeout;
return function (...args) {
const context = this;
const later = () => {
timeout = null;
if (!immediate) func.apply(context, args);
};
const callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
}
参数说明:
func:需要防抖的函数。wait:等待时间(毫秒)。immediate:是否立即执行(true 表示首次触发立即执行,后续等待结束后再执行)。
简化版:
// 防抖函数实现
function debounce(func, delay) {
let timer = null;
return function() {
const context = this;
const args = arguments;
clearTimeout(timer);
timer = setTimeout(() => {
func.apply(context, args);
}, delay);
};
}
2. 节流(Throttle)
核心思想:在一段时间内,无论事件触发多少次,函数最多执行一次。
适用场景:滚动事件(scroll)、鼠标移动(mousemove)、抢购按钮点击。
实现代码(时间戳 + 定时器):
function throttle(func, wait) {
let lastTime = 0;
let timeout;
return function (...args) {
const context = this;
const now = Date.now();
const remaining = wait - (now - lastTime);
if (remaining <= 0) {
// 时间间隔已到,立即执行
if (timeout) {
clearTimeout(timeout);
timeout = null;
}
func.apply(context, args);
lastTime = now;
} else if (!timeout) {
// 设置定时器,确保最后一次触发也能执行
timeout = setTimeout(() => {
func.apply(context, args);
lastTime = Date.now();
timeout = null;
}, remaining);
}
};
}
参数说明:
func:需要节流的函数。wait:执行间隔时间(毫秒)。
简化版:
// 节流函数实现
function throttle(func, delay) {
let timer = null;
return function() {
const context = this;
const args = arguments;
if (!timer) {
func.apply(context, args);
timer = setTimeout(() => {
timer = null;
}, delay);
}
};
}
两者的核心区别
| 防抖(Debounce) | 节流(Throttle) | |
|---|---|---|
| 执行时机 | 事件停止后执行 | 固定时间间隔执行 |
| 类比 | 电梯等人(最后一个人进后关门) | 地铁发车(每隔一段时间发一班) |
使用示例
// 防抖:输入停止 500ms 后执行搜索
const searchInput = document.getElementById("search");
searchInput.addEventListener("input", debounce(searchHandler, 500));
// 节流:每隔 200ms 处理一次滚动事件
window.addEventListener("scroll", throttle(scrollHandler, 200));
通过合理选择防抖或节流,可以有效优化高频事件的性能表现。