在Web开发中,防抖(Debouncing)和节流(Throttling)是两种常用的优化技术,用于提高页面性能和用户体验。它们通过限制函数执行的频率来减少计算资源的消耗,尤其是在处理频繁触发的事件时,如窗口大小调整、滚动、键盘输入等。
1、防抖(Debouncing)
防抖技术的核心思想是在事件频繁触发的情况下,只有在事件触发的一段时间后没有再次触发事件时,才执行目标函数。如果在这段时间内事件再次被触发,则重新计时。
1.1、应用场景
- 输入框实时搜索优化
- 窗口大小调整(resize)事件处理
- 按钮提交事件(防止多次点击)
1.2、实现示例
const debounce = (func, wait) => {
let timeout;
return function() {
const context = this;
const args = arguments;
clearTimeout(timeout);
timeout = setTimeout(() => {
func.apply(context, args);
}, wait);
};
}
2、节流(Throttling)
节流技术的核心思想是在一定时间内只执行一次目标函数。即使在这段时间内事件被多次触发,目标函数也只会被执行一次。
2.1、应用场景
- 滚动事件处理(如无限滚动加载或滚动监听)
- 动画的控制(如避免动画的过度执行)
2.2、实现示例
节流的实现方式有多种多样的,下面介绍几种方式
方案一:基于setTimeout的方式,n个wait周期,执行n次。这种方案有个缺点,最后一个周期内的响应可能会无法被处理
const throttle = (func, wait) => {
let inThrottle;
return function() {
const args = arguments;
const context = this;
if (!inThrottle) {
func.apply(context, args);
inThrottle = true;
setTimeout(() => inThrottle = false, wait);
}
};
}
方案二:基于时间计算实现,相对全面一些,n个wait周期,执行 n + 1 次,确保了最后一个周期的事件也能响应
const throttle = (fn,wait)=>{
let last ,timer
return function(){
let now = Date.now()
if(last && now < last + wait){
clearTimeout(timer)
timer = setTimeout(()=>{
last = now
fn.apply(this,arguments)
},delay)
}else{
last = now
fn.apply(this,arguments)
}
}
}
3、防抖与节流的选择
- 当你希望某些代码在事件停止触发后只执行一次时,使用防抖。
- 当你希望某些代码不管事件触发多少次,都以一定的频率限制执行时,使用节流。
4、结论
防抖和节流是两种重要的前端性能优化技术。它们通过减少事件处理函数的执行频率,帮助避免页面的卡顿和性能问题。在实际开发中,合理选择和使用防抖与节流,可以显著提升用户体验和应用性能。