性能和速度是程序的敌人,以致于每一个优秀的程序员都在孜孜不倦的提升软件的性能和速度,从而提升产品的用户体验。

下面介绍的是debounce和throttle,这两种技术能够改善程序的性能,它们非常相似但是不同的技术。

当dom事件被频繁触发时,使用debounce或throttle就非常有用了,因为它能够在事件和函数执行之间添加一层控制。

这里推荐使用Lodash工具库,引入后直接使用_.debounce 和 _.throttle,非常简单和方便,当然前提是需要理解它们的作用。

debounce防抖动
debounce允许我们把一组调用压缩为单个调用。

想象一下你在电梯里面,门准备关上,突然,有人闯进来,这时电梯不会开始移动,而是门重新打开,然后等待一会。如果还有人进来,它会重复这一过程,直到没有人再进来,最后门自动关上,电梯开始在楼层间移动。这是为什么?因为工程师们也对电梯进行了资源优化,用更少的资源完成任务,充分发挥电梯的效用。这个电梯的例子跟debounce的应用场景非常相似。

应用场景:

调整resize。
当监听了窗口的resize事件时,并且调整浏览器窗口大小的时候,会触发大量的resize事件,所以呢当你拖拽的时候,调用处理函数做大量计算的时候,会发现拖拽的过程有点卡顿,掉帧。
这时我们可以使用debounce,因为我们关注的是最终值,也就是我们最后停止拖动浏览器窗口的值。

input的输入和发送请求。
在input里输入文字然后发送网络请求,有一种较优的方案就是期望用户输入完毕然后再发送网络请求,而不是输入的过程中不断的发出请求,这能有效的优化网络服务。
throttle节流
throttle 只允许在每x毫秒内执行一次操作。

它跟debounce的不同主要是:throttle的执行是有规律的,会每x毫秒内执行一次。

使用场景:
一个相当普遍的例子,用户在使用一个无限滚动的页面,你需要检测用户的位置到底部之间的距离,如果用户接近屏幕底部,我们应该发送Ajax请求更多内容然后添加到页面上。实现这一功能需要监听页面的scroll事件,然而在手机端缓慢的滚动页面会触发上百次事件,这时候有了throttle就可以对其进行优化,比如每250ms内只调用一次,这样用户基本感觉不到有任何体验上的差别,也优化了程序的性能。

在这里我们心爱的debounce是不适合的,因为debounce只在用户停止滚动时才触发(调用)函数。而我们需要的是在用户在滚动页面过程中快要到达底部的时候获取更多内容,使用throttle才能持续的进行检测用户位置到底部之间的距离。

requestAnimationFrame (rAF)
rAF 是对函数的执行进行限速的额外的一种方式。大致等同于_.throttle(dosomething, 16)。但它可以是throttle的替代者,它更流畅和平滑,它是浏览器的标准API。

根据经验,我使用rAF函数的一些场景主要是绘画或动画,重新计算元素的位置等。

触发网络请求或决定是否添加/移除一个class(触发一个CSS动画),我会考虑_.debounce or _.throttle,使用它们你能更灵活的控制执行速率(用200ms替换16ms)。

在underscore或lodash这两个框架里面都没有提供或实现rAF,因为使用它非常的简单。

例子:

var start = null;
var element = document.getElementById(‘SomeElementYouWantToAnimate’);
element.style.position = ‘absolute’;

function step(timestamp) {
if (!start) start = timestamp;
var progress = timestamp - start;
element.style.left = Math.min(progress / 10, 200) + ‘px’;
if (progress < 2000) {
window.requestAnimationFrame(step);
}
}

window.requestAnimationFrame(step);
总结:
使用debounce, throttle and requestAnimationFrame来优化你的事件操作。三者的技术和思路都略微不同,但它们都是非常有用以及彼此互补。

debounce:debounce允许我们把一组事件调用压缩为单个调用。
throttle:每x毫秒执行一次。就像每隔200毫秒检查一次滚动位置。
requestAnimationFrame:可以是throttle的替代者,当你的函数为重新计算和渲染元素到屏幕上,而且你想得到平滑的过渡动画。注意:不支持IE9。
Github:
throttle 和 debounce函数代码

实现思路:

debounce:创建一个指定x毫秒的setTimeout(fn,x),如果在该setTimeout(fn,x)的x毫秒内再次产生新的事件,就会先去取消该setTimeout,然后重新创建一个指定x毫秒的setTimeout(fn,x),不断重复这一过程,直到没有再产生新的事件,x毫秒后调用函数fn。
throttle:setTimeout(fn,x - elapsed)。节流的实现要多两个额外的变量,一个是记录上一次函数fn执行的时间(lastExec),一个是记录流逝的时间(elapsed) = 当前setTimeout创建的时间 - 上一次函数fn执行的时间(lastExec),每产生一个新的事件(创建新的setTimeout),都会先去取消上一个setTimeout,所以它的定时器要这么写setTimeout(fn,x - elapsed)就能每x毫秒执行一次函数fn了,每一次函数fn被执行都会更新lastExec的值为当前时间。

https://www.jianshu.com/p/db8d3233750b

debounce和throttle相关推荐

  1. 白话debounce和throttle

    遇到的问题 在开发过程中会遇到频率很高的事件或者连续的事件,如果不进行性能的优化,就可能会出现页面卡顿的现象,比如: 鼠标事件:mousemove(拖曳)/mouseover(划过)/mouseWhe ...

  2. Debounce 和 Throttle 的原理及实现

    在处理诸如 resize.scroll.mousemove 和 keydown/keyup/keypress 等事件的时候,通常我们不希望这些事件太过频繁地触发,尤其是监听程序中涉及到大量的计算或者有 ...

  3. debounce vs throttle

    debounce vs throttle debounce假设你正在乘电梯上楼,当电梯门关闭之前发现有人也要乘电梯,礼貌起见,你会按下开门开关,然后等他进电梯:如果在电梯门关闭之前,又有人来了,你会继 ...

  4. 浅析Debounce 与 Throttle的区别

    文章目录 概述 Debounce 瞬时响应or延迟响应 举例与注意事项 Throttle 定义 用法举例 参考文章 这两天在学习前端知识,在Vue的官方教程中看到了这两个概念,查阅相关资料后,做以下整 ...

  5. debounce 与throttle

    背景 开发过程中我们会遇到一些场景,事件频繁被触发,导致频繁的DOM操作等,导致UI卡顿 甚至浏览器崩溃等. 1.window对象的resize.scroll 事件 2.拖拽时的mousemove事件 ...

  6. 前端间隔查询的两种方法:Debounce和Throttle

    Debounce 中文名:防抖.在开始操作了之后,那么只有在一段 delay 时间段后不再有操作了,才执行操作. Throttle 中文名:节流.在开始操作之后,在 delay ms 内只会做一次.会 ...

  7. debounce与throttle区别

    在2011年,Twitter网站曾爆出一个问题:在主页往下滚动时,页面会变得缓慢以致没有响应.John Resig发表了一篇文章< a blog post about the problem&g ...

  8. debounce、throttle、useDebounce、useThrottle

    直接使用lodash的debounce会出现以下报错信息 This synthetic event is reused for performance reasons. If you're seein ...

  9. throttle与debounce的区别

    前几天看到一篇文章,我的公众号里也分享了<一次发现underscore源码bug的经历以及对学术界拿来主义的思考>具体文章详见,微信公众号: 文中讲了大家对throttle和debounc ...

最新文章

  1. 将Tensor核心引入标准Fortran
  2. 怎样用vc 做一个c语言,大佬们,小菜鸟想问一问用vc编译器做简易画图软件
  3. 硅谷增长专家 Ian Thiel 来华,首次揭秘数据驱动增长的道与术
  4. 牛逼轰轰!GitHub 上 Star 量最高的 5 个机器学习项目
  5. 嵌入式C语言基础链表
  6. ansys命令流_ANSYS命令流建模3之划分单元+施加弹簧
  7. 这个小伙因WannaCry勒索软件一夜成名,获得一年免费披萨
  8. wx:for双层循环
  9. 年龄是计数还是计量_MSA你只知道计量型和计数型?有哪些类型?分别是什么方法?...
  10. mysql text 性能_MySQL - text 性能优化--记录一
  11. 万字干货,eBPF 中文入门指南
  12. linux命令整理(三)
  13. Teredo Tunnel Adapter: Error Code 10
  14. PC端视频录制软件大集合,看看有没有你用过的?
  15. 脸上用激光手术点完痦子之后出现疤痕增生怎么处理比较好
  16. 17AHU排位赛3 D题 旋转吧!雪月花 ! (DFS序,线段树维护树上最值)
  17. centos 硬盘分区容量调整
  18. TP5查询构造器查询语句select、find、colum、value详解
  19. python文件拓展名是_python文件扩展名是什么
  20. wireshark显示没有找到接口且当cmd界面输入net start npf显示服务名无效解决办法

热门文章

  1. 霍金北京《宇宙的起源》演讲全文
  2. (转载)ACM训练计划,先过一遍基础再按此拼搏吧!!!!
  3. 计算机ppt继续教育,word、excel、PPT继续教育计算机第四次.doc
  4. py实现牛顿迭代法(sympy实现计算函数值和求导)
  5. 小觅智能 | VINS-kidnap 学习笔记
  6. 中国液体早餐市场趋势报告、技术动态创新及市场预测
  7. 为什么程序员的工作效率跟他们的工资不成比例
  8. Web笔记-layerui的基本使用及JavaScript回调函数的写法
  9. JVM存储区划分及是否线程隔离
  10. Nginx提供下载apk服务及扫二维码直接下载.apk