浅析函数防抖节流

防抖和节流都是前端开发中常用的优化性能的技术。

一、定义

防抖:

防抖指的是在事件触发后,在规定的时间内若再次触发,则重新计时,直到规定时间内没有再次触发事件,才执行事件处理。这样可以避免在短时间内频繁地触发事件而导致页面卡顿或者出现错误。

节流:

节流指的是在规定的时间内只执行一次事件处理。在事件被触发后,首先会执行一次事件处理,然后在规定时间内,无论事件被触发多少次,都不会再次执行事件处理,直到规定时间过去后才会执行下一次事件处理。这样可以有效节约资源,提高页面的性能。

两者的区别在于防抖是在最后一次事件触发之后再进行事件处理,而节流则是在规定时间内只执行一次事件处理。

简单理解为

节流: n 秒内只运行一次,若在 n 秒内重复触发,只有一次生效
防抖: n 秒后在执行该事件,若在 n 秒内被重复触发,则重新计时

二、示例

防抖

function debounce(func, delay) {let timer;return function() {clearTimeout(timer);timer = setTimeout(() => {func.apply(this, arguments);}, delay);};
}// 使用防抖函数处理事件
const handleSearch = debounce(function() {// 在这里执行搜索操作
}, 300);// 监听输入框的输入事件,并在防抖函数中处理
input.addEventListener('input', handleSearch);

防抖函数使用了闭包和定时器来实现。当事件触发时,清除之前设置的定时器,然后重新设置一个新的计时器,在规定时间内若再次触发该事件,则重新计时,直到规定时间内没有再次触发事件,才会执行事件处理。这样可以避免在短时间内频繁地触发事件而导致页面卡顿或者出现错误。

具体实现中,首先定义了一个timer变量来保存定时器。然后返回一个匿名函数,当该匿名函数被调用时,会先清除之前设置的定时器,然后重新设置一个新的计时器,等待一段时间后执行目标函数。

节流

function throttle(func, delay) {let timer;let lastTime = 0;return function() {const currentTime = Date.now();if (currentTime - lastTime >= delay) {func.apply(this, arguments);lastTime = currentTime;}};
}// 使用节流函数处理事件
const handleScroll = throttle(function() {// 在这里执行滚动操作
}, 200);// 监听滚动事件,并在节流函数中处理
window.addEventListener('scroll', handleScroll);

节流函数也使用了闭包和定时器来实现。每次事件触发时,判断当前时间和上一次执行事件处理的时间差,只有当时间差超过规定时间间隔时才执行事件处理操作。这样可以有效节约资源,提高页面的性能。

具体实现中,首先定义了一个timer变量来保存定时器,以及一个lastTime变量来保存上一次执行事件处理的时间。然后返回一个匿名函数,当该匿名函数被调用时,会获取当前时间,计算当前时间和上一次执行事件处理的时间差,只有当时间差超过规定时间间隔时才执行事件处理操作,并更新lastTime变量的值。

三、使用场景

  1. 防抖(Debounce)
  • 在用户输入搜索关键字时,可以使用防抖来减少频繁的搜索请求。只有在用户停止输入一段时间后才进行实际的搜索操作。
  • 在窗口大小调整、滚动事件等情况下,可以使用防抖来避免过多的计算和重绘操作。
  1. 节流(Throttle)
  • 在滚动事件处理中,可以使用节流来限制事件处理的频率,减少滚动时的计算量,提高页面性能。
  • 在按钮点击事件或提交表单等情况下,可以使用节流来防止用户重复操作,限制事件的触发频率。

防抖和节流的主要目的是优化性能和提升用户体验,避免不必要的网络请求或频繁的计算和渲染操作。根据具体的业务需求和交互场景,可以选择适合的方式来应用防抖和节流,以达到更好的效果。

四、二者区别

相同点:

  • 目的:防抖和节流都是为了控制事件触发的频率或次数,从而提升性能和用户体验。
  • 实现方式:防抖和节流都可以通过设置定时器来延迟执行或限制执行次数。

不同点:

  1. 触发时机
  • 防抖(Debounce):事件触发后会等待一定的时间间隔(延迟期),只有在延迟期结束后没有再次触发事件时,才会执行事件处理。
  • 节流(Throttle):事件触发后会在固定的时间间隔内执行一次事件处理,无论在这段时间内触发了多少次事件,都只执行一次处理。
  1. 执行次数
  • 防抖:在延迟期内,如果事件触发多次,只会执行一次事件处理,即只执行最后一次触发事件的处理。
  • 节流:在固定的时间间隔内,无论事件触发多少次,都会执行一次事件处理。
  1. 应用场景
  • 防抖 适用于需要等待用户停止操作后再执行的情况,如搜索框输入、窗口调整等场景。
  • 节流 适用于需要限制触发频率的情况,如滚动事件、按钮点击等场景。

就例如,都设置时间频率为500ms,在2秒时间内,频繁触发函数,节流,每隔 500ms 就执行一次。防抖,则不管调动多少次方法,在2s后,只会执行一次
在这里插入图片描述

综上所述,防抖和节流的主要区别在于触发时机和执行次数。防抖用于等待一定时间后执行最后一次操作,节流用于限制在一定时间间隔内执行一次操作。根据具体需求选择适合的方式,可以优化性能和用户体验。

五、优点与存在的不足

防抖的好处:

  1. 减少处理次数:对于频繁触发的事件,使用防抖可以大大减少事件处理的次数,避免过多的计算和渲染,提升性能。
  2. 提升用户体验:防抖可以让用户在停止操作后再执行事件处理,避免了短时间内多次执行处理带来的不必要交互和视觉干扰。
  3. 代码简洁:使用防抖可以通过封装一个函数或组件来统一处理事件,减少重复代码,提高开发效率。

防抖的不足:

  • 延迟期设置不当可能导致误操作:如果将延迟期设置得太长,可能会造成用户的不满或误操作;而设置得太短,则可能会导致事件处理无法完成。
  • 对实时性要求较高的场景不适用:防抖需要等待一段时间才能执行事件处理,因此对于实时性要求较高的场景,如视频播放进度条拖动,防抖并不是最佳选择。

节流的好处:

  1. 控制执行次数:节流可以限制在一定时间间隔内执行事件处理的次数,避免了频繁触发事件带来的性能消耗。
  2. 平滑交互体验:节流可以让事件处理在固定时间间隔内均匀执行,提供更平滑的交互体验,尤其适用于滚动、拖拽等连续触发的场景。
  3. 保留最新状态:由于节流会在固定时间间隔内执行事件处理,可以保留最新的状态或数据,确保处理的准确性和一致性。
  4. 适用于实时性要求不高的场景:相比于防抖,节流可以更加灵活地控制执行次数,适用于实时性要求不高的场景,如页面滚动、搜索建议等。

节流的不足:

  • 延迟响应:由于节流会在固定时间间隔内执行事件处理,可能会造成响应的延迟,特别是在较长的时间间隔设置下。
  • 频率过低可能影响用户体验:如果时间间隔设置得太长,可能会导致事件的实时性不足,影响用户的操作体验。
  • 实现复杂度较高:相比于防抖,实现节流的逻辑相对复杂一些,需要考虑计时器、时间间隔控制等因素,增加了开发的复杂度。

综上所述,防抖和节流都有自己的优点和限制。选择使用哪种方式取决于具体的业务需求、事件类型以及性能和用户体验的权衡。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/204493.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ArrayList与顺序表的简单理解

前言----list 在集合框架中,List是一个接口,继承自Collection。Collection也是一个接口,该接口中规范了后序容器中常用的一些方法,具体如下所示: Iterable也是一个接口,表示实现该接口的类是可以逐个元素进…

编写安全 JavaScript 代码的最佳实践

编写安全 JavaScript 代码的最佳实践 JavaScript 的动态特性使其成为事实上的浏览器语言和世界上最流行的编程语言。 JS 最受欢迎的有用功能之一是即时分析。这意味着浏览器在下载内容的同时执行代码,这显然有其优势。然而,这种程度的自由也伴随着问题…

Redis实战命令

实战命令 单值缓存 set key value get key 对象缓存 (1)set user:1 value(json格式) (2)mset user:1:name junfeng user:1:age 18 mget user:1:name user:1:age 分布式锁 分布式锁解决了什么问题? 分布式锁解…

[带余除法寻找公共节点]二叉树

二叉树 题目描述 如上图所示,由正整数1, 2, 3, ...组成了一棵无限大的二叉树。从某一个结点到根结点(编号是1的结点)都有一条唯一的路径,比如从10到根结点的路径是(10, 5, 2, 1),从4到根结点的路径是(4, 2, 1)&#x…

【中间件】服务化中间件理论intro

中间件middleware 内容管理 intro服务化middleware架构注册中心intro服务治理系统intro 本文主要intro服务化中间件的探讨 去年cfeng写了一篇博客走马观花般阐述了Spring Cloud下面的各种中间件,连深入使用都谈不上,只能说intro,在实际work中…

linux用户身份切换su和 sudo

su 切换root,但是,环境变量是之前用户的 可以看到利用su切换,根目录还是pro1的 su - 连同环境一起切换成root,切换后工作目录都不一样了,看输入内容左侧信息,和第一个图片比较 -c仅执行一次命令&#xff0…

面试必须要知道的MySQL知识--索引

10 索引 10.1 数据页存储结构 10.1.1 数据页的各个部分 在讲索引之前,让我们看看一个单独的数据页是什么样子的 去除掉一些我们不太需要那么关注的部分后,简化如下: 也就是说平时我们在一个表里插入的一行一行的数据会存储在数据页里&#…

k8s-deployment控制器 5

K8s控制器是Kubernetes(简称k8s)系统中一个重要的组成部分,它是一个管理Pod的中间层,可以创建和管理多个Pod副本,确保它们按照预定的数量和行为进行运行。 通过编写yaml文件将信息全部存到etcd中,控制器通…

HTTP协议发展

HTTP 1.0 -> HTTP 1.1 -> HTTP 2.0 -> HTTP 3.0 (QUIC) 每一代HTTP解决了什么问题? 下图说明了主要功能。 HTTP 1.0 于 1996 年最终确定并完整记录。对同一服务器的每个请求都需要单独的 TCP 连接。 HTTP 1.1 于 1997 年发布。TCP 连接可以保持打开状态…

Flask教程入门

1.学习Flask之前,首先需要对URL进行一定的了解。 URL的一些知识: 1.URL只能包含ASCII码里面一些可显示的字符,如A-Z,a-z,0-9,&,#,%,?,/等字符…

spring boot项目未将resource目录标志为资源目录导致配置文件无效因而运行报错问题

能编译,但不能运行。感觉配置文件没有生效。 将程序代码发给同事,我自己能跑,他不能跑,提示无法构造redis对象。redis的链接写在配置文件里,其实是可以连接的。然后从GIT库下载代码,也同样不能跑。同事的操…

外网IP和内网IP的区别

首先得先知道什么是ip地址,它就是唯一标识连接网络的设备的,即IP地址充当了设备在网络中的“住址”,使得设备能够相互通信和交换数据。 我们常听开发人员说外网内网,那么它们有什么区别呢? 外网可以理解为互联网&…

Springboot的excel导出

这里导出excel用到的是 阿里巴巴的easyexcel 1、首先导入依赖 <!--alibaba easyexcel--><dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>2.1.6</version> </dependency> 2、…

第二十章——多线程

一.线程简介 线程的特点 1.进程是资源分配的最小单位&#xff0c;线程是最小的执行单位 2.一个进程可以有多个线程 3.线程共享进程资源 二.创建线程 1.继承Thread类 1.Thread类是java.lang包中的一个类&#xff0c;从这个类实例化的对象代表线程&#xff0c;程序员启动一个新…

三 STM32F4使用Sys_Tick 实现微秒定时器和延时

更多细节参考这篇 1. 什么是时钟以及作用 1.1 什么是时钟 时钟是由电路产生的周期性的脉冲信号&#xff0c;相当于单片机的心脏 1.2 时钟对于STM32的作用 指令同步&#xff1a;cpu和内核外设使用时钟信号来进行指令同步数据传输控制&#xff1a; 时钟信号控制数据在内部总…

sqli-labs(6)

27. 过滤了union和select 使用双写绕过 有报错信息使用报错注入 1and(extractvalue(1,concat(0x5c,database())))and11 1and(updatexml(1,concat(0x7e,database(),0x7e),1))and11 1and(extractvalue(1,concat(0x5c,(selseselectlectect(group_concat(table_name))from(inform…

Spring Boot 3 + Spring Security 6 最新版本修改 Json 登录后 RememberMe 功能问题失效的解决方案

当 Spring Boot 版本更新到 3 之后&#xff0c;最低要求的 JDK 版本变为 17&#xff0c;相应的 最新版本的 Spring Security 的配置也发生了变化&#xff0c;一下主要讲解一些新的 Spring Security 的配置方法 1. 配置由继承WebSeucrityConfigurerAdapter变成只需添加一个Secur…

每天五分钟计算机视觉:LeNet是最早用于数字识别的卷积神经网络

LeNet 假设你有一张 32321 的图片,然后使用 6 个 55的过滤器,步幅为 1,padding 为 0,输出结果为 28286。图像尺寸从 3232 缩小到 2828。 然后进行池化操作,使用平均池化,过滤器的宽度为 2,步幅为 2,图像的尺寸,高度和宽度都缩小了 2 倍,输出结果是一个14146 的图像。…

【LeetCode】挑战100天 Day13(热题+面试经典150题)

【LeetCode】挑战100天 Day13&#xff08;热题面试经典150题&#xff09; 一、LeetCode介绍二、LeetCode 热题 HOT 100-152.1 题目2.2 题解 三、面试经典 150 题-153.1 题目3.2 题解 一、LeetCode介绍 LeetCode是一个在线编程网站&#xff0c;提供各种算法和数据结构的题目&…

Redis 持久化机制

client Redis[内存] --> 内存数据、磁盘数据----> 磁盘&#xff0c;Redis官方提供了两种不同的持久化方案将内存中的数据存储在硬盘中&#xff1a; 快照&#xff08;Snapshot&#xff09; AOF只追加日志文件。 1、快照&#xff08;Snapshot&#xff09; 1、快照的特点…