前端开发:JS的节流与防抖

news2024/9/30 15:29:27

前言

在前端实际开发中,有关JS原生的节流和防抖处理也是很重要的点,关于底层和原理的掌握使用,尤其是在性能优化方面甚为重要。作为前端开发的进阶内容,在实际开发过程中节流和防抖通常都是项目优化的必要手段,而且也是非常常用的优化手段,因为在前端程序中防止用户短时间内快而高频地多次操作触发动作执行,最常用的就是页面提交按钮,为了防止用户多次点击重复提交触发表单多次提交的问题,还有就是为了防止用户在拖动滑动条的时候,多次触发加载更多等情况。所以在JS中节流与防抖的使用也是比较常用的知识点,而且在前端求职面试的时候二者也是必考知识点,可以说非常重要,那么本文就来做一下总结,方便查阅使用。

闭包

由于在JS中的节流与防抖都是属于闭包的应用范畴,所以想要理解防抖和节流,首先要理解闭包。

闭包:一个函数和对其周围状态(lexical environment,词法环境)的引用捆绑在一起(或者说函数被引用包围),这样的组合就是闭包(closure)。也就是说,闭包让你可以在一个内层函数中访问到其外层函数的作用域。在 JavaScript 中,每当创建一个函数,闭包就会在函数创建的同时被创建出来。

通俗的说,闭包就是能够读取其他函数内部变量的函数。由于在 JavasSript 语言中,只有函数内部的子函数才能读取局部变量,所以闭包可以简单理解成"定义在一个函数内部的函数"。在本质上看,闭包是将函数内部和函数外部连接起来的桥梁。 想要了解闭包的详细内容可以阅读三掌柜的这篇文章:前端开发:JS中闭包的使用详解前端开发:JS中闭包的使用详解_js闭包的使用_三掌柜666的博客-CSDN博客

JS节流与防抖

在前端开发过程中,为了提高应用程序性能,在用户进行窗口操作和输入框操作时候多次提交或者滑动的时候,如果未对事件处理函数调用频率做限制的时候,会增加浏览器和服务器的负担,造成用户体验感非常差,甚至有些滑动事件由于自身复杂的计算回调函数频繁调用会引起前端页面的卡顿。还有就是在绑定scroll、resize事件时,当它发生的时候被触发的频率非常高、间隔很近,尤其是日常开发的页面中,事件中涉及到大量的位置计算、DOM操作、元素重绘等等,这些都无法在下一个scroll事件出发前完成,就会引起浏览器的卡帧,严重影响用户体验感。

针对这些问题,提高用户体验,优化程序性能,就可以采用节流和防抖的方式来解决这些问题,把多次计算汇合成一次计算,只操作一个精确点即可,这样可以减少事件函数的调用频率,减轻了浏览器负担,提高了程序性能,提高了用户体验。

另外,防抖动和节流本质是不一样的。防抖是多次触发但最后只会执行一次,节流是多次触发但周期内只会执行一次。函数节流与函数防抖都是为了限制函数的执行频次,以优化函数触发频率过高导致的响应速度跟不上触发频率,出现延迟,假死或卡顿的现象。接下来就来详细解答二者具体的区别。

 

节流是什么?

节流(throttle):当持续触发事件时候,保证一定时间段内只调用一次事件处理函数,也就是持续触发事件,每隔一段时间只执行一次函数。节流的策略是,在每个时间周期内,不论触发多少次事件,只执行一次动作。在上一个时间周期结束后,如果又有事件触发,则开始新的时间周期,同理,在新的时间周期里只执行一次动作。 和防抖类似,节流策略也分前缘和延迟两种。延迟是指周期结束后执行动作,前缘是指执行动作后再开始周期。

节流使用场景:有很多,比如图片懒加载的使用、进行ajax数据请求加载的使用、下滑自动加载数据、侧边浮动导航栏等等。

函数节流:指在一定时间周期内执行的操作只执行一次,也就是预先设定一个执行周期,当调用动作的时间大于等于执行的周期则执行该动作,接着进入下一个新周期。一个函数执行一次后,只有大于设定的执行周期后才会执行第二次。

节流函数的实现

节流函数的适用场景主要在拖拽场景和缩放场景中,如固定时间内只执⾏⼀次,防⽌超⾼频次触发位置变动;以及监控浏览器的resize等场景。具体实现示例如下所示:

const throttle = (fun, delay) => { //fun是事件处理程序,delay是事件执行的延迟事件,单位为毫秒

let timer = null;

return (...args) => {

clearTimeout(timer); //每次触发事件,需要把定时器清理之后重新计时

timer = setTimeout(() => {

fun.apply(this, args); //执行事件处理程序

timer = null; //事件执行之后把清除定时器,待下次触发事件的时候重新设置

}, delay);

};

};

防抖是什么?

防抖(debounce):在持续触发事件的时候,一定时间段内没有再触发事件,事件处理函数才会执行一次,如果设定的时间到来之前,又一次触发了事件,就重新开始延时。防抖一定是在事件触发N秒后才会执行,若在一个事件触发的N秒内又触发了该事件,以新的事件时间为准,N秒过后才执行,等触发事件N秒内不再触发事件才执行。也就是多次快速频繁地触发事件,只会执行一次事件函数,前提是需要加上一个时间限制。也可以理解为,为了防止快速且频繁的触发事件而导致多次执行事件函数引起程序卡顿等问题,可以设置在多次触发的事件只执行一次事件函数,且需要设定一个间隔时间,若两次事件触发的间隔时间低于设定的时间,就是频繁操作。

防抖的特点是当事件快速连续不断触发时,动作只会执行一次。分为两种,一种是延迟debounce,一种是前缘debounce。 延迟debounce,是在周期结束时执行,前缘debounce,是在周期开始时执行。但当触发有间断,且间断大于我们设定的间隔时间时,动作就会有多次执行。

防抖使用场景:有很多,比如监听滚动事件、鼠标移动事件onmousemove、频繁点击表单提交按钮等。

函数防抖:是指在一定时间内,在动作被连续频繁触发的情况下,动作只会被执行一次,也就是当调用动作过N秒后,才会执行该动作,若在这N秒内又调用该动作则将重新计算执行时间,所以短时间内的连续动作只会触发一次。

防抖函数的实现

防抖函数的适用场景主要在防止多次提交场景,比如防⽌多次提交按钮,只执⾏最后提交的⼀次;输入框输入的时候,只执⾏⼀段连续的输⼊事件的最后⼀次;以及搜索框进行搜索联想词功能。具体实现示例如下所示:

const debounce = (fun, delay) => { //fun是事件处理程序,delay是事件执行的延迟事件,单位为毫秒

let timer = null;

return (...args) => {

clearTimeout(timer); //每次触发事件,需要把定时器清理之后重新计时

timer = setTimeout(() => {

fun.apply(this, args); //执行事件处理程序

}, delay);

};

};

防抖与节流注意事项

在使用节流和防抖的时候,要注意以下的点:

①闭包的运用

实际中要避免全局的命名污染,所以不建议使用全局变量,同时为了让所需要的变量能够得到缓存,所以使用闭包存储部分需要用到的变量。

②this指向以及event参数

由于在事件触发调用的时候,是由防抖或者节流函数return返回出来的函数,而不是事件函数,事件函数是作为参数传入防抖或者节流函数中的,所以它的this指向是window,而不是触发事件调用函数的dom。同理可知,事件自带的event参数也是拿不到的,所以需要通过闭包去存储this上下文以及argument这个传递给函数的参数的类数组对象。事实上,所有的高阶函数内部都需要特别注意this的绑定 。

节流与防抖的总结

防抖:其实就是维护一个定时器,把多个相同的操作合并成一个操作,规定在delay后触发函数,若在此之前触发函数,则取消之前的计时重新计时,只有最后一次操作才能被触发。

节流:原理就是判断是否达到一定的时间周期来触发事件,规定某个时间段内只能触发一次函数。

节流与防抖区别:防抖只会在最后一次事件后执行触发函数;节流不管操作事件多么的频繁都会保证在规定时间段内触发事件函数。

最后

通过本文关于前端开发JS中的节流与防抖的详细介绍,不管是在实际的前端开发工作中还是在前端求职面试中都是非常关键的知识点,所以作为前端开发者来说必须要掌握它相关的内容,尤其是从事前端开发不久的开发者来说尤为重要,是一篇值得阅读的文章,重要性就不在赘述。欢迎关注,一起交流,共同进步。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Project】项目管理软件学习笔记

一、前言使用Project制定项目计划步骤大致如下:以Project2013为例,按照上图步骤指定项目计划。二、实施2.1 创建空白项目点击文件——新建——空白项目,即完成了空白项目的创建,在此我把该项目保存为60mm项目管理.mpp,…

深入浅出1588v2(PTP)里的时间同步原理

1.时间同步1.1 单步同步(OneStep)单步同步最为简单,master向slave发送一个sync的同步包,同步包里带有这条信息发送时master的当前时间t1,假如这条信息从master传输到slave需要的传输时间是D,那么slave收到信息时,maste…

芯驰(E3-gateway)开发板环境搭建

1-Windows下环境配置 可以在Windows上使用命令行或者IAR IDE编译SSDK项目。Windows编译依赖的工具已经包含在 prebuilts/windows 目录中,包括编译器、Python和命令行工具。 1.1.1 CMD SSDK集成 msys 工具,可以在Windows命令行中完成SDK的配置、编译和…

嵌入式系统硬件设计与实践(第一步下载eda软件)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】 现实生活中,我们经常发现有的人定了很多的目标,但是到最后一个都没有实现。这听上去有点奇怪,但确实是实实在在…

Mysql数据库总结

一.MySQL 的基础1.架构图Mysql逻辑架构图主要分三层:(1)第一层负责连接处理,授权认证,安全等等 (2)第二层负责编译并优化SQL (3)第三层是存储引擎。Mysql 服务器的默认端…

Welcome to TryHackMe --- 我在TryHackMe学习的第90天

我在TryHackMe学习的第90天 自发的thm玩家交流企鹅群:751273347 TryHackMe是一个及其优秀的道德嗨客学习平台 这三个月里,我在TryHackMe都学了什么 TryHackMe的几个路径我觉得是按照oscp出的,所以理论上讲我应该差不多有oscp水准&#xff…

ElasticSearch修改索引字段类型

一、Es报MapperParsingException异常 线上功能报错,一看日志是往es中添加数据报错,错误日志如下: org.elasticsearch.index.mapper.MapperParsingException: failed to parse field [categoryId] of type [integer] in document with id 16…

软件技术知识库必备的功能清单及注意事项!

文档是一个迭代过程。它可能需要根据客户反馈进行改进,或者可能需要折射文档中已包含的某些内容。知识库可以包括客户的常见问题或对解决方案的更多参考,这些解决方案可能需要包括这些解决方案,以提高效率、生产力并降低公司成本,…

百趣代谢组学分享—揭示水稻“生长-防御”平衡调控机制!

湖南农业大学科研团队揭示水稻“生长—防御”平衡调控机制! 文章标题:Rice cellulose synthase-like protein OsCSLD4 coordinates the trade-off between plant growth and defense 发表期刊:Frontiers in Plant Science 影响因子&#x…

【个人总结】超详细Neo4j安装下载

【个人总结】超详细Neo4j安装下载一、下载1.1 Jdk下载1.2 Neo4j下载:二、安装配置2.1 解压2.2 配置三、启动Neo4j一、下载 1.1 Jdk下载 下载neo4j之前,需要下载jdk,这里默认已经下载过jdk,,若未下载可参考之前文章:h…

17.标准库特殊设施

文章目录标准库特殊设施17.1tuple类型17.1.1定义和初始化tuple访问tuple的成员关系和相等运算符17.1.2使用tuple返回多个值17.2bitset类型(后续需要时再详细了解)17.3正则表达式17.4随机数bernoulli_distribution类17.5IO库再探标准库特殊设施 17.1tuple类型 tuple(定义在tupl…

Spark工作原理

1)Spark工作原理: 首先看中间是一个Spark集群,可以理解为是Spark的 standalone集群,集群中有6个节点 左边是Spark的客户端节点,这个节点主要负责向Spark集群提交任务,假设在这里我们向Spark集群提交了一个任…

周赛334(前缀和、贪心+双指针、Dijkstra求最短路径、二分答案)

文章目录[6369. 左右元素和的差值](https://leetcode.cn/problems/left-and-right-sum-differences/)前缀和[6368. 找出字符串的可整除数组](https://leetcode.cn/problems/find-the-divisibility-array-of-a-string/)超长整数如何取余?[6367. 求出最多标记下标](ht…

9.3 IGMPv3

实验目的 熟悉IGMPv3的应用场景掌握IGMPv3的配置方法实验拓扑 实验拓扑如图9-22所示: 图9-22:IGMPv3 实验步骤 (1)配置IP地址 MCS1的配置 MCS1的IP地址配置如图9-23所示: 图9-23:配置MCS1的IP地址 MCS2…

结构体字节对齐、偏移量

复习下struct的大小、成员偏移量offsetof,说下我的理解: 64位下默认对齐数default8原则1:struct中每一个成员变量tmp的对齐数realmin{default,tmp} struct Student {int num;//0char name[8];double score; } stu; 这个结构体stu中&#x…

阿里前端二面经典手写面试题汇总

实现类的继承 实现类的继承-简版 类的继承在几年前是重点内容,有n种继承方式各有优劣,es6普及后越来越不重要,那么多种写法有点『回字有四样写法』的意思,如果还想深入理解的去看红宝书即可,我们目前只实现一种最理想…

rollup环境配置

VUE2.x源码学习笔记 1. rollup环境配置 首先在VScode中新建文件夹vue_sc,然后终端打开定位到打开的文件夹,输入“npm init -y”初始化配置项,运行成功之后文件夹新增package.json文件 继续在终端运行"npm install babel/preset-env ba…

浅析Tomcat架构上的Valve内存马(内存马系列篇十一)

写在前面 这篇也是在Tomcat容器上面构造的内存马(收回之前说的不搞Tomcat了),这是建立在Tomcat的管道上面做文章的一个内存马的实现方式。这是内存马系列的第十一篇文章了。 前置 什么是Pipeline-Valve管道? 根据前面Tomcat架构的相关知识&#xff0…

腾讯云卖向“有币”区块链

曾经坚决“不涉币”的腾讯云将业务延伸向“有币区块链”。 在首届 Web3 全球峰会“腾讯云Web3构建日”上,腾讯云宣布进军Web3,并公开了与Ankr、Avalanche、Scroll和Sui 四个原生区块链项目的合作,其中前两个项目都发行了加密货币&#xff0c…

关于Java中的静态块讲解

文章目录类的加载特性与时机类加载的特性类加载的时机static的三个常用地方什么是静态块?特点写法静态块 static怎么用?类的加载特性与时机 在介绍static之前可以先看看类的相关 类加载的特性 在JVM的生命周期里,每个类只会被加载一次。 类加载的原则&#xf…