快速搞懂防抖和节流

56 阅读4分钟

JavaScript 防抖与节流:定义与核心应用场景

防抖和节流是 JavaScript 中用于控制高频事件触发频率的两种核心优化方案,目的是减少不必要的函数执行,提升页面性能和用户体验,二者在实现逻辑和适用场景上有本质区别。

一、防抖(Debounce)

1. 核心定义

防抖的核心逻辑是:触发高频事件后,函数不会立即执行,而是等待一段指定时间(延迟时间)后再执行;若在这段时间内事件再次被触发,则重新计时,只有当事件停止触发且超过延迟时间,函数才会执行一次

可以通俗理解为:“等最后一次触发后,再冷静一会儿才执行”,类似电梯关门(有人进电梯就重新计时,没人进了才关门)。

2. 简单实现(非立即执行版)

javascript

运行

function debounce(fn, delay = 300) {
  let timer = null; // 保存定时器标识
  return function(...args) {
    // 每次触发事件,清除之前的定时器,重新计时
    clearTimeout(timer);
    timer = setTimeout(() => {
      fn.apply(this, args); // 执行目标函数
    }, delay);
  };
}

3. 核心应用场景

防抖适用于「事件触发频繁,但只需执行最后一次结果」的场景:

  • 搜索框输入联想:用户连续输入关键词时,无需每次输入都请求接口,等待用户停止输入(如 300ms 内无新输入)后,再触发搜索接口请求,减少无效请求;
  • 窗口大小调整(resize) :用户拖拽窗口改变大小时,会高频触发 resize 事件,用防抖只在用户停止拖拽后,执行一次页面布局调整逻辑;
  • 滚动条滚动到底部检测:无需滚动过程中频繁检测,等待滚动停止后再判断是否到达底部;
  • 按钮防重复点击:如提交订单按钮,防止用户快速连续点击导致重复提交,防抖可确保只有最后一次点击(或点击后延迟)触发提交逻辑;
  • 输入框实时校验(非即时) :如手机号、邮箱格式校验,等待用户输入完成后再校验,避免输入过程中频繁提示错误。

二、节流(Throttle)

1. 核心定义

节流的核心逻辑是:高频事件触发时,限制函数在指定时间间隔内只能执行一次,无论事件触发多少次,都会按照固定频率执行函数

可以通俗理解为:“固定时间内,只执行一次”,类似水龙头滴水(无论怎么开关,每隔一段时间只滴一滴水)。

2. 简单实现(时间戳版)

javascript

运行

function throttle(fn, interval = 500) {
  let lastTime = 0; // 记录上一次函数执行时间
  return function(...args) {
    const nowTime = Date.now(); // 获取当前时间
    // 若当前时间与上一次执行时间的差值超过间隔,才执行函数
    if (nowTime - lastTime >= interval) {
      fn.apply(this, args);
      lastTime = nowTime; // 更新上一次执行时间
    }
  };
}

3. 核心应用场景

节流适用于「事件触发频繁,且需要按固定频率执行函数」的场景:

  • 滚动条滚动监听(如加载更多) :用户滚动页面时,无需每次滚动都触发加载逻辑,设置每隔 500ms 检测一次滚动位置,判断是否需要加载更多数据;
  • 鼠标移动 / 拖拽事件(mousemove/drag) :如拖拽元素时,频繁触发 mousemove 事件,用节流固定频率更新元素位置,避免页面卡顿;
  • 高频点击按钮(如点赞、刷新) :限制用户点赞频率(如 1 秒内只能点赞 1 次),防止恶意刷赞;
  • 视频 / 音频播放进度更新:无需实时更新进度条,每隔 200ms 更新一次即可,减少 DOM 操作;
  • 窗口滚动时的导航栏吸顶 / 吸底:滚动过程中按固定频率判断滚动距离,触发导航栏样式切换,避免频繁操作 DOM。

三、防抖与节流的核心区别

特性防抖(Debounce)节流(Throttle)
核心逻辑等待最后一次触发后,延迟执行一次固定时间间隔内,只执行一次
执行时机事件停止触发后(延迟结束)事件触发过程中(按固定频率)
触发频率取决于事件停止触发的时间,可能很久执行一次固定频率执行,不受事件触发频率影响
核心目的过滤无效触发,保留最后一次结果控制执行频率,避免过度执行
通俗比喻电梯关门(有人进就重新计时)水龙头滴水(固定时间滴一滴)

四、总结

  1. 防抖:“最后一次触发后延迟执行”,适合「只需最终结果」的场景(搜索联想、按钮防重复点击);
  2. 节流:“固定频率执行”,适合「需要持续反馈」的场景(滚动加载、鼠标拖拽);
  3. 二者本质都是减少高频事件的函数执行次数,提升页面性能,实际开发中可直接使用 lodash 库的 _.debounce() 和 _.throttle()(成熟稳定,支持更多配置)。