节流 VS 防抖 相关知识点与面试题

文章目录

  • [防抖 (Debounce) 与 节流 (Throttle)](#防抖 (Debounce) 与 节流 (Throttle))
    • [一、 核心定义与区别](#一、 核心定义与区别)
      • [1. 防抖 (Debounce)](#1. 防抖 (Debounce))
      • [2. 节流 (Throttle)](#2. 节流 (Throttle))
      • [3. 对比总结](#3. 对比总结)
    • [二、 使用场景](#二、 使用场景)
      • [🛠 防抖 (Debounce) 的使用场景](#🛠 防抖 (Debounce) 的使用场景)
      • [⚙️ 节流 (Throttle) 的使用场景](#⚙️ 节流 (Throttle) 的使用场景)
    • [三、 使用它们的好处](#三、 使用它们的好处)
    • [四、 常见面试题](#四、 常见面试题)
      • [A. 手写实现一个基础版防抖](#A. 手写实现一个基础版防抖)
      • [B. 手写实现一个基础版节流(定时器版)](#B. 手写实现一个基础版节流(定时器版))

防抖 (Debounce) 与 节流 (Throttle)

在前端开发中,防抖节流是优化高频率执行代码(如滚动、输入、调整窗口大小)的核心手段。


一、 核心定义与区别

1. 防抖 (Debounce)

  • 定义 :在事件被触发 n n n 秒后再执行回调,如果在这 n n n 秒内事件又被触发,则重新计时
  • 形象比喻:就像电脑的**"待机睡眠"**。你最后一次操作鼠标后,电脑开始倒计时 10 分钟;如果你在第 9 分钟动了一下,倒计时立刻重置,重新等 10 分钟。

2. 节流 (Throttle)

  • 定义 :规定在一个单位时间内,只能触发一次函数。如果这个单位时间内触发了多次函数,只有一次生效。
  • 形象比喻 :就像**"红绿灯""水龙头滴水"**。无论路口有多少辆车想冲过去,绿灯亮起的时间间隔是固定的;或者水龙头每隔 3 秒滴一滴水,中间你如何拧开关都没用。

3. 对比总结

特性 防抖 (Debounce) 节流 (Throttle)
核心逻辑 重置计时器,只执行最后一次 锁定执行周期,每隔一段时间执行一次
关注点 关注"空闲时间",等到彻底安静后再执行 关注"执行频率",在持续触发中按节奏执行
执行次数 无论触发多少次,最终可能只执行一次 持续触发时,会按固定频率执行多次

二、 使用场景

🛠 防抖 (Debounce) 的使用场景

  • 搜索框输入 (Input):用户不停输入字符时,没必要每打一个字就发一次 AJAX 请求,等用户停下 500ms 后再发送。
  • 窗口大小调整 (Resize):用户拉伸窗口时,等拉伸结束再重新计算布局或 ECharts 图表自适应。
  • 表单提交按钮:防止用户因为手抖或网络延迟快速多次点击,导致重复提交订单或数据。

⚙️ 节流 (Throttle) 的使用场景

  • 鼠标移动 (Mousemove):在实现拖拽效果时,每秒计算几十次位置足够了,不需要每微秒都计算。
  • 滚动监听 (Scroll):监听用户滚动到底部加载更多(Infinite Scroll),每 200ms 检查一次距离即可。
  • 游戏技能释放:无论玩家按键多快,技能的冷却时间(CD)是固定的,强制限制触发频率。

三、 使用它们的好处

  1. 性能优化:减少 CPU 和内存的占用,避免高频操作导致页面卡顿、掉帧。
  2. 节省资源:显著减少向后端发送 API 请求的次数,减轻服务器压力和带宽消耗。
  3. 提升用户体验:避免因为无效的重复计算或异步请求冲突导致页面响应混乱。

四、 常见面试题

A. 手写实现一个基础版防抖

javascript 复制代码
function debounce(fn, delay) {
  let timer = null;
  return function(...args) {
    if (timer) clearTimeout(timer); // 只要进来就清空之前的计时
    timer = setTimeout(() => {
      fn.apply(this, args);
    }, delay);
  };
}

B. 手写实现一个基础版节流(定时器版)

javascript 复制代码
function throttle(fn, delay) {
  let timer = null;
  return function(...args) {
    if (!timer) { // 如果没锁,就设置一个定时器
      timer = setTimeout(() => {
        fn.apply(this, args);
        timer = null; // 执行完后解锁
      }, delay);
    }
  };
}
相关推荐
郭老二10 小时前
【前端】vue3:编译步骤
前端
不在逃避q11 小时前
Trae/Vs Code/Cursor命令行无法跑npm命令
前端·arcgis·npm
夏殇之殁11 小时前
包中创建自定义列表项。 . 使用自定义列表项进行数据绑定 . 将天气预报数据保存到本地内存表,通过LiveBindings进行显示。 ...
服务器·前端·javascript
The Chosen One98511 小时前
高进度算法模板速记(待完善)
java·前端·算法
陈随易11 小时前
MoonBit抓包模块pcap,查看电脑的每一次联网通信
前端·后端·程序员
新中地GIS开发老师12 小时前
WebGIS开发学生作品|低空航天管理与航线规划系统
前端·javascript·webgis·三维gis开发
用户0595401744613 小时前
大模型对话记忆持久化踩坑实录:用 Playwright 自动化测了 300 次,终于揪出会话丢失的真凶
前端·css
丙氨酸長鏈13 小时前
Web前端入门第 问:JavaScript 一个简单的 IndexedDB 数据库入门示例
前端·javascript·数据库
kyriewen14 小时前
面试官让我手写虚拟列表——AI生成的版本,快速滚动几下就白屏了
前端·javascript·面试
IT_陈寒14 小时前
Vite热更新失效?你可能漏了这个配置
前端·人工智能·后端