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