2024年最新前端性能优化之防抖与节流,大幅度降低你的事件处理性能,有备无患

读者福利

========

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

由于篇幅过长,就不展示所有面试题了,想要完整面试题目的朋友(另有小编自己整理的2024大厂高频面试题及答案附赠)


Title
我是内容1
我是内容2
我是内容3
我是内容4
我是内容5
我是内容6
我是内容7
我是内容8
我是内容9

效果展示

在这里插入图片描述

我们可以看到, scroll事件是一个频发事件,我们只是简单的往下滚动, 但scroll 事件却触发了很多很多很多次。 但是我们的目的可能只是想获得滚动停下来以后导航栏距离文档顶部的距离, 我们并不需要滚动停止前那过程中变化的距离, 如果一直在滚动时去获取距离,这非常影响性能,这是我们就需要用到 防抖和节流了。

二、防抖


(1)定义

抖,听起来就是一个频繁触发的动作,我们可以想象我们在跑步,每跑一步就出很多的汗,我们跑的过程中,很想拿毛巾擦一擦汗,但是一想,如果刚擦完汗,跑几步就又出汗了,还不如不擦,我看看我等会还跑不跑,如果还跑,那我就一直不擦汗,如果我什么时候不跑了,我就开始擦一下汗。那么‘ 跑步 ’ 这个动作就可以看作我们上述代码中的滚动事件, ’ 擦汗 ’ 就可以看成scroll 事件的处理代码,即获取导航栏离文档顶部的距离。 那么防抖,就是我们滚动页面,刚要获取导航栏离文档顶部的距离,但是发现等会还要继续滚动,那么就先不获取了,等什么时候停止滚动了,再获取这个距离。

以上文字就是对防抖这个概念的一个形象的解释,希望大家反复阅读,理解了定义以后才方便理解下面的实现防抖的代码。

(2)使用

为了解决我们正文刚开始那个例子中,频繁获取导航栏离文档顶部的距离的现象,我们可以用一个setTimeout定时器来完成防抖功能

// 这里我们只修改js代码,其他都不变

我们来解读一下这段代码:

  1. 我们在全局定义了一个用于存放定时器的变量timer, 当我们在网页第一次滚动页面时,触发scroll 事件, 首先判断 timer 是否有定时器, 因为第一次滚动触发事件,并没有定时器赋值给timer, 所以执行下面的代码, 这时给 timer 赋值一个延迟为500ms的定时器,并将获取导航栏离文档顶部距离的代码放在定时器中。

  2. 因为滚动事件是频繁触发的,紧接着又触发了 scroll 事件。同样的先判断 timer 是否有定时器, 因为上一次触发该事件给 timer 赋值了一个定时器, 但此时定时器还没结束, 所以 timer 是有定时器的,所以执行 if 语句里的代码, 将 timer 里的定时器给清除掉, 这时,因为在上一次定时器还没结束时,我们就在下一次触发事件时将上一次的定时器给清除掉了,所以上一次触发事件没有来得及运行获取导航栏离文档顶部距离的代码。接着我们又给 timer 赋值了一个定时器。

  3. 就这样在后面会触发无数次的滚动事件, 代码的运行会一直按照步骤2里的逻辑进行,这样循环往复……

  4. 直到我们停止滚动以后, 不再触发滚动事件了,最后一次滚动事件中给 timer赋值的 setTimeout 定时器 生效了,并打印了数据。

现在,我们来看一下,运用了防抖之后滚动页面会有什么效果

在这里插入图片描述

我们可以很清楚的看到,在我们滚动的过程中,一直没有打印数据,直到我们停止以后, 控制台打印了导航栏离文档顶部的距离。这就是防抖的效果,现在你有没有对防抖有一个很深的印象了呢? 接下来我们来介绍一下第二种处理频繁触发事件的方法: 节流。

三、节流


(1)定义

为了介绍节流的定义,我们继续使用跑步这一例子。想象我们在跑步,我们很热很热,在跑步的过程中,每隔几秒钟,拿毛巾擦一擦身上的汗。这里我们同样把 ’ 跑步 ’ 看作是 滚动页面的操作, 把 ’ 擦汗 ’ 看作是获取导航栏离文档顶部的距离的操作。那么,节流就是, 我们滚动页面,获取了一下导航栏离文档顶部的距离, 此时我们一直在滚动页面, 只不过我们刚获取过距离了,就先不获取了, 等距离上一次获取几秒后,我们再获取一次吧。

也请大家仔细体会节流的含义,方便理解下面的代码

(2)使用

节流的方法,有两种,一种是利用时间戳,另一种是利用定时器

  • 利用时间戳来完成节流

代码如下:

// 同样的这里也是只需要修改js代码

我们来解读一下这段代码:

  1. 我们刚开始滚动页面,触发滚动事件,获取当前时间戳, 因为是第一次触发该事件,last = 0 ,所以 if 语句成立,获取一次导航栏离文档顶部的距离,并给 last 赋值一个现在的时间戳。

  2. 因滚动事件频繁触发, 再一次触发了滚动事件,获取一下现在的时间戳,判断一下,现在的时间戳减去上一次操作结束时的时间戳,发现时间相差小于1秒,所以不获取导航栏离文档顶部的距离,同时也不用给 last 重新赋值一个此时的时间戳

  3. 就这样一直频繁触发滚动事件,按照步骤2循环往复……

  4. 直到距离上次操作超过1秒, now - last 大于1秒后,才会再一次获取导航栏离文档顶部的距离,并又一次给 last 赋值一个操作结束时的时间戳。

JavaScript

  • js的基本类型有哪些?引用类型有哪些?null和undefined的区别。

  • 如何判断一个变量是Array类型?如何判断一个变量是Number类型?(都不止一种)

  • Object是引用类型嘛?引用类型和基本类型有什么区别?哪个是存在堆哪一个是存在栈上面的?

  • JS常见的dom操作api

  • 解释一下事件冒泡和事件捕获

  • 事件委托(手写例子),事件冒泡和捕获,如何阻止冒泡?如何组织默认事件?

  • 对闭包的理解?什么时候构成闭包?闭包的实现方法?闭包的优缺点?

  • this有哪些使用场景?跟C,Java中的this有什么区别?如何改变this的值?

  • call,apply,bind

  • 显示原型和隐式原型,手绘原型链,原型链是什么?为什么要有原型链

  • 创建对象的多种方式

  • 实现继承的多种方式和优缺点

  • new 一个对象具体做了什么

  • 手写Ajax,XMLHttpRequest

  • 变量提升

  • 举例说明一个匿名函数的典型用例

  • 指出JS的宿主对象和原生对象的区别,为什么扩展JS内置对象不是好的做法?有哪些内置对象和内置函数?

  • attribute和property的区别

  • document load和document DOMContentLoaded两个事件的区别

  • JS代码调试

  • 开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值