JavaScript中的性能优化:防抖与节流
字数 619 2025-11-23 17:18:10
JavaScript中的性能优化:防抖与节流
防抖(Debounce)和节流(Throttle)是两种常用的性能优化技术,主要用于控制函数在高频事件中的执行频率,避免过度消耗资源。
1. 问题场景
当处理scroll、resize、input等高频事件时,回调函数会被频繁触发。例如搜索框的实时搜索,如果每次输入都立即请求接口,会导致大量无效请求。
2. 防抖的实现原理
防抖的核心:在事件触发后等待一段时间再执行函数,若在等待期内事件再次触发,则重新计时。
function debounce(func, delay) {
let timeoutId;
return function (...args) {
clearTimeout(timeoutId); // 清除之前的计时器
timeoutId = setTimeout(() => func.apply(this, args), delay);
};
}
- 应用场景:搜索框输入停止500ms后才搜索;窗口resize结束后再计算布局。
3. 节流的实现原理
节流的核心:在一段时间内最多执行一次函数,如同水龙头限流。
function throttle(func, delay) {
let lastCall = 0;
return function (...args) {
const now = Date.now();
if (now - lastCall >= delay) {
func.apply(this, args);
lastCall = now;
}
};
}
- 应用场景:滚动加载(每隔200ms检查一次位置);按钮防重复点击。
4. 进阶对比
- 防抖:连续操作时只执行最后一次(如输入停止后搜索)。
- 节流:均匀间隔执行(如滚动时定期计算位置)。
- 可视化比喻:防抖是"电梯关门"(等人进完),节流是"地铁发车"(固定间隔发车)。
5. 立即执行变体
防抖可支持立即执行第一次操作:
function debounceImmediate(func, delay, immediate) {
let timeoutId;
return function (...args) {
const callNow = immediate && !timeoutId;
clearTimeout(timeoutId);
timeoutId = setTimeout(() => {
timeoutId = null;
if (!immediate) func.apply(this, args);
}, delay);
if (callNow) func.apply(this, args);
};
}
6. 实际应用技巧
- 使用Lodash的
_.debounce或_.throttle获得更健壮的实现(含取消功能)。 - 结合RAF(RequestAnimationFrame)实现动画节流:
requestAnimationFrame(throttle(callback, 16))。