节流 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);
    }
  };
}
相关推荐
FungLeo32 分钟前
成为全栈·Vue 管理后台篇·分类树与标签管理:层级数据如何落到管理界面
前端·javascript·vue.js·分类树·naive ui·标签管理·前端数据结构
总要学点什么1 小时前
第108篇:三维特效-图片轨迹线效果——把贴图滚成一串箭头,想用它的本色反而整条消失
开发语言·javascript·ecmascript·gis·webgl·材质·cesium
Lank_M4 小时前
白底都占八成,PNG 为何只在图表页赢过 JPG
前端
张一凡934 小时前
给 Coding Agent 加一道"架构闸门":Jin 是如何做到"先审架构、再写代码、不漂移"的
前端·后端·agent
Linye4 小时前
AI 写的 HTML 原型全是空壳?聊聊真实 DOM 交互避坑
前端·人工智能
ZANE4 小时前
纯前端实现的 PDF 与图片互相转换工具技术实现
前端
Swot4 小时前
SvelteKit Remote Functions 使用指南
前端·后端
Cooper254 小时前
三源热榜去重加 AI 摘要:URL 唯一键踩出的三个坑
前端·python
Yk酱228405 小时前
A2UI探索随笔-技术选型
前端
前端繁华如梦5 小时前
# 从 73000 行压缩代码到 TypeScript 模块化:我把一个 Three.js FPS 游戏 1:1 复刻了一遍
前端