在 JavaScript 中,防抖(Debounce) 和 节流(Throttle) 是两种优化函数执行频率的方法。它们的主要目的是提升性能,特别是在处理用户频繁触发的事件时(如 resize
、scroll
、mousemove
、keypress
、input
等)。
防抖(Debounce)
防抖的核心思想是:让某个函数在一段时间内不被重复调用,只有在最后一次调用后延迟的时间内没有再次触发,才会执行该函数。
应用场景
- 搜索框输入:用户停止输入后,发送请求。
- 窗口大小调整:停止调整窗口后,重新计算布局。
实现原理
使用 setTimeout
和 clearTimeout
,每次触发事件时重置计时器。
代码实现
function debounce(func, delay) {
let timer;
return function(...args) {
const context = this;
clearTimeout(timer); // 清除之前的定时器
timer = setTimeout(() => {
func.apply(context, args); // 延迟后执行函数
}, delay);
};
}
使用例子
// 防抖函数
const handleResize = debounce(() => {
console.log('Window resized');
}, 500);
// 绑定事件
window.addEventListener('resize', handleResize);
节流(Throttle)
节流的核心思想是:让某个函数在规定的时间间隔内最多执行一次。
应用场景
- 滚动加载:每隔一段时间检查是否滚到底部。
- 防止按钮重复点击。
- 页面滚动时只触发一次计算位置的操作。
实现原理
可以通过时间戳或 setTimeout
的方式实现。
代码实现
时间戳方式
function throttle(func, delay) {
let lastTime = 0;
return function(...args) {
const now = Date.now();
if (now - lastTime >= delay) {
func.apply(this, args);
lastTime = now;
}
};
}
定时器方式
function throttle(func, delay) {
let timer;
return function(...args) {
if (!timer) {
timer = setTimeout(() => {
func.apply(this, args);
timer = null;
}, delay);
}
};
}
使用例子
// 节流函数
const handleScroll = throttle(() => {
console.log('Scroll event triggered');
}, 1000);
// 绑定事件
window.addEventListener('scroll', handleScroll);
防抖 vs 节流
特性 | 防抖(Debounce) | 节流(Throttle) |
---|---|---|
定义 | 在最后一次事件触发后执行一次 | 每隔固定时间执行一次 |
核心思想 | 多次触发合并为一次 | 限制频率,间隔执行 |
应用场景 | 搜索输入、窗口调整等,用户停止操作后才执行 | 滚动加载、按钮防抖等,限制频繁触发 |
实现方式 | setTimeout | setTimeout 或 时间戳 |
通过合理使用防抖和节流,可以有效提高性能和用户体验,根据场景选择适合的策略即可。