当前位置: 首页 > news >正文

防抖(debounce)和节流(throttle)实现及原理讲解

防抖和节流是前端开发中常用的两种性能优化技术,主要用于控制事件触发的频率。下面我将分别介绍它们的实现和原理。

防抖(debounce)

原理

防抖的核心思想是:在事件被触发后,等待一段时间再执行回调函数。如果在这段时间内事件又被触发,则重新计时。这样可以确保只有在事件停止触发一段时间后才会执行回调。

适用场景

  • 搜索框输入联想(等待用户停止输入后再发送请求)

  • 窗口大小调整(等待调整结束后再计算布局)

  • 表单验证(等待用户停止输入后再验证)

实现代码

function debounce(fn, delay) {let timer = null;return function(...args) {// 每次触发时清除之前的定时器clearTimeout(timer);// 设置新的定时器timer = setTimeout(() => {fn.apply(this, args);}, delay);};
}

使用示例

// 模拟一个搜索函数
function search(query) {console.log(`搜索: ${query}`);
}// 创建防抖版本的搜索函数
const debouncedSearch = debounce(search, 500);// 模拟连续输入
debouncedSearch('a');
debouncedSearch('ab');
debouncedSearch('abc');
// 只有最后一次调用会在500ms后执行

节流(throttle)

原理

节流的核心思想是:在一定时间间隔内,只执行一次回调函数。无论这段时间内事件触发多少次,都只执行一次。

适用场景

  • 滚动事件监听(每隔一段时间检查位置)

  • 鼠标移动事件(限制处理频率)

  • 按钮点击防重复提交

实现代码

时间戳版本
function throttle(fn, delay) {let lastTime = 0;return function(...args) {const now = Date.now();// 如果距离上次执行时间超过了delay,则执行if (now - lastTime >= delay) {fn.apply(this, args);lastTime = now;}};
}
定时器版本
function throttle(fn, delay) {let timer = null;return function(...args) {if (!timer) {timer = setTimeout(() => {fn.apply(this, args);timer = null;}, delay);}};
}
结合版本(更精确)
function throttle(fn, delay) {let timer = null;let lastTime = 0;return function(...args) {const now = Date.now();const remaining = delay - (now - lastTime);clearTimeout(timer);if (remaining <= 0) {fn.apply(this, args);lastTime = now;} else {timer = setTimeout(() => {fn.apply(this, args);lastTime = Date.now();}, remaining);}};
}

使用示例

// 模拟一个处理滚动函数
function handleScroll() {console.log('处理滚动事件');
}// 创建节流版本的处理函数
const throttledScroll = throttle(handleScroll, 200);// 模拟频繁滚动事件
window.addEventListener('scroll', throttledScroll);
// 无论滚动多快,最多每200ms执行一次

防抖与节流的区别

特性防抖(debounce)节流(throttle)
触发频率只在事件停止触发后执行固定时间间隔执行
执行次数多次触发只执行一次多次触发按固定频率执行
适用场景搜索联想、窗口resize滚动事件、鼠标移动
效果等待用户完成操作稀释操作频率

实际应用技巧

  1. 参数选择

    • 防抖的延迟时间通常设置为300-500ms

    • 节流的间隔时间根据场景不同,滚动事件常用16ms(60fps)或100ms

  2. 立即执行版本
    有时候我们需要防抖函数在第一次触发时立即执行,然后才开始防抖:

    function debounceImmediate(fn, delay, immediate = true) {let timer = null;return function(...args) {const callNow = immediate && !timer;clearTimeout(timer);timer = setTimeout(() => {if (!immediate) {fn.apply(this, args);}timer = null;}, delay);if (callNow) {fn.apply(this, args);}};
    }
  3. 取消功能:
    可以为防抖和节流函数添加取消功能:

    function debounceWithCancel(fn, delay) {let timer = null;const debounced = function(...args) {clearTimeout(timer);timer = setTimeout(() => {fn.apply(this, args);}, delay);};debounced.cancel = function() {clearTimeout(timer);timer = null;};return debounced;
    }

    防抖和节流是前端性能优化的重要技术,合理使用可以显著提升页面性能和用户体验。

http://www.dtcms.com/a/306092.html

相关文章:

  • dify离线插件打包步骤
  • Apache Ignite 与 Spring Data 集成
  • Electron + Fabric 打包遇到error LNK2001
  • 【面试场景题】随机立减金额计算
  • JVM——内存布局、类加载机制及垃圾回收机制
  • Http401和403什么意思
  • 颐顿机电携手观远BI数据:以数据驱动决策,领跑先进制造智能化升级
  • 皮尔逊相关系数的理论基础、统计特性与应用局限
  • 操作系统:总结(part_1,part_2)
  • Python Pandas.get_dummies函数解析与实战教程
  • Python在自动化与运维领域的核心角色:工具化、平台化与智能化
  • 从零开始,在Windows环境部署vllm
  • Boost.Asio:探索异步I/O引擎核心
  • stm32的PID控制算法
  • 学习游戏制作记录(冻结敌人时间与黑洞技能)7.30
  • 【音视频】WebRTC 开发环境搭建-Web端
  • Apple基础(Xcode②-Flutter结构解析)
  • ica1靶机练习
  • K8s 备份与恢复利器:Velero 实战指南
  • MySQL常见面试题
  • springboot本地访问https链接,证书错误
  • Spark的宽窄依赖
  • Kubernetes 中 ConfigMap 与 Secret 的深度解析
  • gaussdb demo示例
  • Spring Cloud Gateway静态路由实战:Maven多模块高效配置指南
  • 时序数据库厂商 TDengine 发布 AI 原生的工业数据管理平台 IDMP,“无问智推”改变数据消费范式
  • ES 文件浏览器:多功能文件管理与传输利器
  • 数据建模怎么落地?从概念、逻辑到物理模型,一文讲请!
  • Kubernetes高级调度02
  • 《超级秘密文件夹》密码遗忘?试用版/正式版找回教程(附界面操作步骤)