debounce 与 throttle 区别
原文地址:http://undefinedblog.com/debounce-and-throttle/
二、什么是debounce
1. 定义
如果用手指一直按住一个弹簧,它将不会弹起直到你松手为止。
也就是说当调用动作n毫秒后,才会执行该动作,若在这n毫秒内又调用此动作则将重新计算执行时间。
三、什么是throttle
1. 定义
如果将水龙头拧紧直到水是以水滴的形式流出,那你会发现每隔一段时间,就会有一滴水流出。
也就是会说预先设定一个执行周期,当调用动作的时刻大于等于执行周期则执行该动作,然后进入下一个新周期。
在实现一些需要被频繁调用的函数时,我们通常都会使用 debounce
或 throttle
方法。在我的印象中,它们的作用就是减少函数被调用的次数,但具体有什么区别,却真的不能说清楚。
直到最近看了一篇精彩的博文,用可视化的方法展示了两者的区别,很有启发性,值得参考。
注意到上图,第一行 Mousemove Events
展示了 mousemove
事件触发的频率。第二行和第三行是分别使用 underscore 与 jQuery 的 debounce 方法后事件的触发频率。第四、五行则是增加了一个 delay 参数后的触发频率。与之对比的是最后三行,使用的是 throttle 方法。
首先我们的直观感觉是使用 debounce 方法相比于 throttle 方法事件触发的频率更低,但实际上不能这么理解。要解释上图的结果,首先需要了解 debounce 和 throttle 的原理。
当我们阅读 lodash 的代码时会发现,throttle 方法不过是 debounce 方法的一个修饰。也就是说,_.throttle 和 _.debounce 最终都会都会调用 debounce 方法。那么 debounce 究竟是如何工作的呢?
首先看 _.debounce 的 API:
_.debounce(func, delay, options);
func 是需要被调用的目标函数,delay 是时间限制,options 是一系列的配置,为了简化问题,这里不多提。
当调用 _.debounce 后,会返回一个函数,这个函数在被调用时会生成一个 setTimeout(delayed, delay)。其中 delayed 又是一个内部方法,在 delayed 被调用时进行如下检测:当前时间 - 上次func被调用事件 是否 小于 0 或 大于 delay ?如果是则执行一次 func,记录并返回执行结果,同时更新上次被调用时间;如果不是则调用 setTimeout 进行下一次的判断。
因此,当你像下面这样绑定事件,
$(window).on('mousemove', _.debounce(moveHandler, 500));
并频繁移动鼠标时,你会发现 moveHandler 压根没有被调用过!直到你停下来后,moveHandler 才会被调用一次。
至于 _.throttle 方法,只不过是多给 debounce 传了一个 maxWait 选项,这个选项的意思是至少保证在每 maxWait 时间让 func 被调用一次。
说到这儿,你应该就明白了为什么会出现上图那样的调用情况。如果你频繁的移动鼠标,throttle 会保证在每 maxWait 时间调用 func 一次,而 debounce 如果没有明确设置 maxWait,是一直不会调用 func 直到你停止移动鼠标后才会调用一次。
因此,可以笼统的说 _.throttle 就是设置了 leading=true, trailing=true 及 maxWait 的 _.debounce。
那什么时候该用 debounce 什么时候该用 throttle 呢?
下面我列举了一些场景:
- input 中输入文字自动发送 ajax 请求进行自动补全: debounce
- resize window 重新计算样式或布局:debounce
- scroll 时更新样式,如随动效果:throttle
最重要的还是理解两者对调用时间及次数上的处理,根据业务逻辑选择最合适的优化方案!
debounce 与 throttle 区别的更多相关文章
- debounce与throttle区别
在2011年,Twitter网站曾爆出一个问题:在主页往下滚动时,页面会变得缓慢以致没有响应.John Resig发表了一篇文章< a blog post about the problem&g ...
- 试议常用Javascript 类库中 throttle 与 debounce 辅助函数的区别
问题的引出 看过我前面两篇博客的童鞋可能会注意到都谈到了事件处理的优化问题. 在很多应用中,我们需要控制函数执行的频率, 例如 窗口的 resize,窗口的 scroll 等操作,事件触发的频率非常高 ...
- 白话debounce和throttle
遇到的问题 在开发过程中会遇到频率很高的事件或者连续的事件,如果不进行性能的优化,就可能会出现页面卡顿的现象,比如: 鼠标事件:mousemove(拖曳)/mouseover(划过)/mouseWhe ...
- Debounce 和 Throttle 的原理及实现---防止频繁触发某事件
原文:http://blog.csdn.net/redtopic/article/details/69396722 在处理诸如 resize.scroll.mousemove 和 keydown/ke ...
- 防抖(Debounce)与节流( throttle)区别
http://www.cnblogs.com/ShadowLoki/p/3712048.html http://blog.csdn.net/tina_ttl/article/details/51830 ...
- 函数防抖与函数节流 封装好的debounce和throttle函数
/** * 空闲控制 返回函数连续调用时,空闲时间必须大于或等于 wait,func 才会执行 * * @param {function} func 传入函数,最后一个参数是额外增加的this对象,. ...
- underscore里面的debounce与throttle
throttle 策略的电梯.保证如果电梯第一个人进来后,15秒后准时运送一次,不等待.如果没有人,则待机. debounce 策略的电梯.如果电梯里有人进来,等待15秒.如果又人进来,15秒等待重新 ...
- debounce、throttle、requestAnimationFrame
今天review同事代码,代码实现了返回顶部的功能,用到了lodash库中的throttle,我看着眼生,于是乎去看了下lodash文档,然后牵出了debounce,具体的知识点,这里不再赘述,底部的 ...
- debounce还是throttle(去抖和节流)
debounce 去抖 我的理解很简单,比方说window.onscroll会疯狂触发handler,此时给它一个debounce(handler, delayTime). 就是不管你延时时间内触发了 ...
随机推荐
- sorted() ,filter() ,map()的用法
sorted() 排序函数. 语法: sorted(Iterable, key=None, reverse=False) Iterable: 可迭代对象 key: 排序规则(排序函数), 在sorte ...
- rhel6.4 根目录扩容
状况:根目录容量不足 解决:扩容根目录 ====================================================== 解决步骤: 1. 将新的磁盘加入服务器 2. 使用 ...
- JAVA学习一 对象数组
对象数组 今天在写一个代码,才发现自己对于对象数组的理解是不够的,那么就讲讲自己现在的理解. 对于数组中的每一个元素都是一个针对对象的引用 他会指向你的具体的一个堆上的对象,它本身知识一个地址值,与其 ...
- ArrayMap java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Object[]
错误堆栈: java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Object[] at android ...
- find的详细使用
对我我这个出学者,这个已经算是很难了,不过今天整理了一下,感觉还可以接受. find Linux中十分重要的一个查找功能, [root@moban /]# find /tmp/ -type f -na ...
- 责任链模式的使用-Netty ChannelPipeline和Mina IoFilterChain分析
本文来自网易云社区 作者:乔安然 1. Chain of Responsiblity 定义: 使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系.将这个对象连成一条链,并沿着这条链 ...
- linux内存
在Linux的世界中,从大的方面来讲,有两块内存,一块叫做内存空间,Kernel Space,另一块叫做用户空间,即User Space.它们是相互独立的,Kernel对它们的管理方式也完全不同 驱动 ...
- gitbash避免每次push都输入密码
gitbash每次提交都要输密码真有点头疼,所以就: 1 创建验证文件:touch .git-credentials(windows) 2 编辑验证文件:vim .git-credentials ...
- QC的使用学习(一)
今天学习的时间很少,就利用睡前的一点时间来学习一下刚安装好的QC. 1.后台站点管理.主要是对八大选项的了解: site project:顾名思义,就站点项目管理,管理域和项目. site user: ...
- python 基础篇 10 函数进阶
本节主要内容:1. 函数参数--动态传参2. 名称空间, 局部名称空间, 全局名称空间, 作⽤域, 加载顺序.3. 函数的嵌套4. gloabal, nonlocal关键字 ⼀. 函数参数--动态传参 ...