防抖 节流_防抖节流与前端性能优化

5a01d93dc04a5530b19ce3ac2bcb5a8e.png

在我们日常的开发中经常会用到一些容易被反复触发的事件。比如:scroll、resize、鼠标事件(mousemove,mouseover等)、键盘事件(keyup、keydown)。

频繁触发回调导致的大量计算会引发页面的抖动甚至卡顿。为了规避这种情况,我们需要一些手段来控制事件被触发的频率。就是在这样的背景下,throttle(事件节流)和 debounce(事件防抖)出现了。

“节流”与“防抖”的本质

这两个东西都以闭包的形式存在。

它们通过对事件对应的回调函数进行包裹、以自由变量的形式缓存时间信息,最后用 setTimeout 来控制事件的触发频率。

Debounce

防抖的概念其实是从机械开关和继电器的“去弹跳”(Debounce)衍生 出来的,基本思路就是把多个信号合并为一个信号。

手机拍照也有相似的概念,在拍照的时候手如果拿不稳晃的时候拍照,一般手机是拍不出好照片的,因此智能手机是在你按一下的时候连续拍许多张, 能过合成手段,生成一张,也就是我们平常说的HDR。翻译成JS就是,事件内的N个动作会被忽略,只有事件后由程序触发的动作才是有效的。

将目标方法(动作)包装在setTimeout里面,然后这个方法是一个事件的回调函数,如果这个回调一直连续执行,那么这些动作就一直不执行。为什么不执行呢,我们搞了一个clearTimeout,这样setTimeout里的方法就不会执行! 为什么要clearTimeout呢,我们就需要将事件内的连续动作删掉嘛!待到用户不触发这事件了。那么setTimeout就自然会执行这个方法。那么这个方法用在什么地方呢,就是用于input输入框架的格式验证,假如只是验证都是字母也罢了,太简单了,不怎么耗性能,如果是验证是否身份证,这性能消耗大,你可以隔170ms才验证一次,或者更长的时间。这时就需要这个东西。或者你这个是自动校验,需要将已有的输入数据往后端拉一个列表,频繁的交互,后端肯定耗不起,这时也需要这个,如隔350ms。下面我们来实际写一个防抖:

// fn是我们需要包装的事件回调, delay是每次推迟执行的等待时间
function debounce(fn, delay) {
  // 定时器
  let timer = null

  // 将debounce处理结果当作函数返回
  return function () {
    // 保留调用时的this上下文
    let context = this
    // 保留调用时传入的参数
    let args = arguments

    // 每次事件被触发时,都去清除之前的旧定时器,这里是闭包,timer变量必须清除
    if(timer) {
        clearTimeout(timer)
    }
    // 设立新定时器
    timer = setTimeout(function () {
      fn.apply(context, args)
    }, delay)
  }
}

// 用debounce来包装scroll的回调
const better_scroll = debounce(() => console.log('触发了滚动事件'), 1000)

document.addEventListener('scroll', better_scroll)

Throttle

节流的概念可以想象一下水坝,你建了水坝在河道中,不能让水流动不了,你只能让水流慢些。换言之,你不能让用户的方法都不执行。如果这样干,就是debounce了。为了让用户的方法在某个时间段内只执行一次,我们需要保存上次执行的时间点与定时器。下面来实际写一个节流:

// fn是我们需要包装的事件回调, interval是时间间隔的阈值        由于是闭包,last值可以保存上次的触发时间,不会重置为0if (now - last >= interval) {

用 Throttle 来优化 Debounce

debounce 的问题在于它“太有耐心了”。试想,如果用户的操作十分频繁——他每次都不等 debounce 设置的 delay 时间结束就进行下一次操作,于是每次 debounce 都为该用户重新生成定时器,回调函数被延迟了不计其数次。频繁的延迟会导致用户迟迟得不到响应,用户同样会产生“这个页面卡死了”的观感。

为了避免弄巧成拙,我们需要借力 throttle 的思想,打造一个“有底线”的 debounce——等你可以,但我有我的原则:delay 时间内,我可以为你重新生成定时器;但只要delay的时间到了,我必须要给用户一个响应。这个 throttle 与 debounce “合体”思路,已经被很多成熟的前端库应用到了它们的加强版 throttle 函数的实现中:

// fn是我们需要包装的事件回调, delay是时间间隔的阈值
       timer = setTimeout(

 如果觉得本文对你有所帮助,不如点个在看再走。

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

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

相关文章

惠普10代的服务器有哪些型号,英特尔官方科普:秒懂十代酷睿型号怎么认!

今日,英特尔官方微博再次放出科普:十代酷睿处理器是如何命名的?英特尔介绍,以酷睿i7-1065G7为例,“i7”为产品型号,“1065”中的“10”代表十代酷睿,“65”为CPU代号,“G7”为显卡性…

form提交后台注解拿不到数据_浏览器是如何将用户数据发送到服务器的?

今天是刘小爱学习Java的第89天。感谢你的观看,谢谢你。话不多说,开始今天的学习:在学习之前,先思考如下问题:对于浏览器来说:如何将用户数据发送到服务器呢?数据传输的格式是怎么样的呢&#xf…

proxmoxve打造云桌面_微软云电脑Cloud PC曝光:配置一般还不便宜

光纤宽带的普及和提速、5G的兴起,让云电脑、云游戏、云手机等产品和应用红火起来。而微软也正在开发一款名为Cloud PC的云端Windows操作系统,并计划2021年正式推出。据报道,Cloud PC是由Azure云服务支撑,基于虚拟桌面打造的&#…

alpine linux图形界面_跟光磊学Linux运维-Linux入门与基本使用

认识Linux用户在安装CentOS8.2时,设置过root用户的密码,同时也创建了用户guanglei。其中root用户是系统自带的管理员账户,也被称为超级用户,root用户接近系统完整的控制能力,对系统损害几乎有无限的能力。运维人员在生…

休眠 嵌入式_内幕消息:嵌入式软件挤出最低功耗模式

低功耗运行仍然是各行业应用的关键驱动因素。随着睡眠模式的增加,电源管理突然从单纯的硬件问题转移到软件开发人员必须考虑的事情上。功耗模式的最简单应用是当系统空闲时,将其置于休眠状态。然而,今天的MCU提供多种低功耗模式,进…

cnn 验证集 参与训练吗_一个简单的零基础的机器学习教程之二,字母数字验证码识别...

一.前言基于前面我发的贴子 土味程序员:一个简单的零基础的机器学习教程,Pytorch搭建Faster R-CNN目标检测平台​zhuanlan.zhihu.com一个非常震撼的目标检测的例子。上个帖子从环境安装到调试代码再到图片检测视频检测一个详细的教程,今天我来…

activiti 文档_免费、开源、多平台的PDF文档处理软件——PDFsam Basic

今天给大家推荐的是一款免费、开源、多平台支持的PDF文档处理软件——PDFsam BasicPDFsam Basic是为普通用户提供的免费开源解决方案,提供了PDF文档拆分、合并、混合、提取页面和旋转等等功能。01. 文档分割PDFsam Basic可以通过给定页码、书签级别,把PD…

@data注解不生效_你说啥什么?注解你还不会?

点击蓝色字免费订阅,每天收到这样的好信息前言:最近有不少粉丝关注本公众号。并且我已经成功开通了流量主同时会赚一点点广告费,我打算每个月把这部分钱拿出来给大家买点书刊,算是给大家一点福利吧。大家想买什么书扫描下方的加他拉你加群。最后,非常感谢大家的关注…

yearning 2. 部署_对于企业来说,在选择协同办公系统的时候,选择私有化部署的数据安全一些,还是使用云服务器比较安全?...

当然是私有化部署!因为它除了安全,还有个性化~私有化部署,简单理解就是企业自己购买或租赁服务器,或者由服务商提供免费的云资源,然后将整个系统部署在企业自有的服务器上。采用这种方式,企业就不用担心自家…

numpy 平方_Numpy的终极备忘录

作者|Rashida Nasrin Sucky 编译|VK 来源|Towards Data Science Python是开源的。对于使用python的数据科学家来说,Numpy这个库是必不可少的。其他一些基本的库,如Pandas,Scipy是建立在Numpy的基础上。所以我决定做一份备忘录。这里我包括了到…

linux HZ 值_Linux的serial串口控制台

本人大多数情况都是在调试服务器大量的linux服务器,很多情况下也不没有必要专门准备KVM(keyboard, video, mouse),甚至有些机器根本就没有显示器接口。如何调试的?闲来无事,分享一下。有些人说“ 给我个Lin…

nginx文件系统大小_详解Nginx系列

1.Nginx特点Nginx是一个事件驱动架构,而非传统过程驱动架构。具有内存占用低,当并发连接大时,能够预测内存使用率。Nginx改变了传统的web服务器体系架构,提高了响应速度,起初Nginx开发的目标是实现10倍以上的性能&…

不可用于python编程开发的是_Python编程语言可做而不应做的一些事是什么_Python视频_Python视频教程_编程语言_课课家...

在 -5 ~ 256 之间的整型数值可以进行互换 当我在考虑这个能用在什么地方的时候,我有点迷茫了。撇开这点,你在此之前知道 Python 中的数字是可以改变其实际含义的吗?之所有会有这种情况,是因为 Python 解释器为 -5 ~ 256 之间的每一…

iphone7尺寸_iPhone 12 mini、12 Pro Max真机对比图赏:尺寸直观感受下

11月6日消息,等待多时,苹果iPhone 12 mini、iPhone 12 Pro Max将于今晚21点正式开启预定,11月13日发售。iPhone 12 mini是苹果尺寸最小、最轻薄的5G手机,而iPhone 12 Pro Max则是综合实力最强大,拍照最好的iPhone。赶在…

人脸识别错误代码437是什么意思_lol手游repeat ready check fails什么意思 解决攻略大全...

导读 lol手游repeat ready check fails什么意思?在日服内出现英文的错误代码,这两种语言的差异,会让国服玩家变得越来越混乱,想要解决问题,还是一如既往的得弄清楚代码内提示的内容是什么... lol手游repeat ready chec…

matlab求傅里叶级数展开式_连续时间的傅里叶级数

如果信号x(t)是周期信号,那么对于所有t,存在一个最小正数T,使得x(t)x(tT)其中T为这个周期信号的最小正周期。根据周期函数的周期性:x(t)x(tN*T)(N为整数)称为这个信号的基波频率周期信号x(t)也可以用周期复指数信号表示则因为x(t)是周期信号&…

delphi chart 曲线实时_发展学生曲线跑能力的体育游戏及运用研究

不想错过精彩的推送?戳左上角蓝字“体育教师大本营”关注并点击右上角●●●菜单栏选择“设置⭐️标”或“置顶公众号”每天早上7:00,体委伴您成长 一、曲线跑教材跑是人类在日常生活社会交往、生产劳动中的基本活动能力之一,从一定程度上反映…

拖拽的方式使用qbuttongroup_【无机纳米材料科研制图——Photoshop 0402】PS使用选框工具修改图片/图层...

此篇,我们来分享使用PS的选框修改图片。一、栅格化图形。1)同时选中两个图层。首先,回到上一篇中图片相互遮挡的状态。在上一篇中,我们通过调整图层的上下位置,避免了遮挡的情况,但有时候只通过调整图层的上…

pagerank数据集_从小白视角理解数据挖掘十大算法

关注上方“数据挖掘工程师”,选择星标,关键时间,第一时间送达!作者 | 雪山飞猪链接 | https://www.cnblogs.com/chenqionghe/p/12301905.html编辑 | 深度学习这件小事本文仅作技术交流,如有侵权,请联系删除…

filter过滤器_JavaWeb之 Filter(过滤器)

FIlter作用过滤器JavaWeb三大组件之一,它与Servlet很相似!不它过滤器是用来拦截请求的,而不是处理请求的。当用户请求某个Servlet时,会先执行部署在这个请求上的Filter,如果Filter“放行”,那么会继承执行用…