浏览器中有一些事件会高频率触发,比如:
- resize
- scroll
- mousemove
- ...
如果我们监听这些事件,并按浏览器的触发频率响应,极可能造成页面卡顿、抖动,甚至浏览器崩溃。
图1:感受下 onScroll 的触发频率
debounce(防抖)和 throttle(节流)是一种编程技巧,用于控制某个函数在一定时间内执行多少次。主要用于平滑事件响应、减轻浏览器压力。
1. debounce(防抖)
debounce(防抖)策略是当事件被触发时,设定一个周期延迟执行动作,若期间又被触发,则重新设定周期,直到周期结束,执行动作。
举例:电梯门快要关了,突然有人准备上来,梯门会再次打开。只有当梯门完全关闭后,才开始运送。
图2:debounce 时序图
——图片来源:csdn,hupian1989
debounce 还有一个叫 leading edge debounce(前沿防抖)的变种,区别在于它是在周期开始的时候执行动作,而不是周期结束的时候。
图3:leading edge debounce 时序图
——图片来源:csdn,hupian1989
图4:debounce 动画演示
1.1. 应用示例
图5:在 onScroll 中应用 debounce
1.2. 哪里有现成的工具?
lodash 里面有:
_.debounce(func, [wait=0], [options={}])
underscore 里面也有:
_.debounce(function, wait, [immediate])
1.3. 基本原理
图6:最简单的 debounce 实现
1.4. underscore 的 debounce 实现分析
图7:underscore 的 debounce 实现分析
2. throttle(节流)
throttle(节流)的策略是在固定周期内,只执行一次动作,若有新事件触发,则不执行。周期结束后,又有事件触发,开始新的周期。
举例:从第一个人进入电梯后开始算,固定时长后准时运送一次。如果没有人,则不运行。
图8:throttle 时序分析
——图片来源:csdn,hupian1989
throttle 与 debounce 一样,也有一个 leading edge throttle 的变种;
图9:leading edge throttle 时序分析
——图片来源:csdn,hupian1989
2.1. 应用场景
图10:onScroll 事件中应用 throttle 技术
2.2. 哪里有现成的工具?
lodash 里面有:
_.throttle(func, [wait=0], [options={}])
underscore 里面也有:
_.throttle(function, wait, [options])
2.3. 基本原理
图11:最简单的 throttle 实现
2.4. underscore 的 throttle 实现分析
图12:underscore 的 throttle 实现分析
参考:
https://css-tricks.com/debouncing-throttling-explained-examples/ https://johnresig.com/blog/learning-from-twitter/ http://benalman.com/projects/jquery-throttle-debounce-plugin/