使用场景
某些场景下,一些计算量比较大的函数,操作 DOM 函数等函数会被频繁调用执行,而且由于人的反应有限实际不需要那么多计算,就会造成极大的性能浪费。
举个例子
当使用鼠标滚轮时可以轻松触发每秒30个事件。但是,我在测试中,智能手机中的慢速滚动可能会触发每秒多达100个事件。你的滚动处理程序是否真的需要这个执行速度?
下面我列举一些场景
- window对象的resize、scroll事件,如处理图片懒加载
- 拖拽时的mousemove事件
- 键盘 keyup 事件
- ...
原理
那么throttle 和 debounce 函数是怎样做的呢?
这里引用经典的举例
想象每天上班大厦底下的电梯。把电梯完成一次运送,类比为一次函数的执行和响应。假设电梯有两种运行策略 throttle 和 debounce ,超时设定为15秒,不考虑容量限制。
1.throttle 策略的电梯。保证如果电梯第一个人进来后,15秒后准时运送一次,不等待。如果没有人,则待机。
2.debounce 策略的电梯。如果电梯里有人进来,等待15秒。如果又人进来,15秒等待重新计时,直到15秒超时,开始运送。
用我的一句话说是,throttle 在一段时间内最多执行一次,而 debounce 是在接下来一段时间内没有再次调用,则执行。
实现
由于说了是简单实现,那么就把最核心的部分拿出来
debounce
function debounce (cb, delay) {
var timer = null;
return function () {
clearTimeout(timer);
timer = setTimeout(cb, delay);
}
}
throttle
function throttle (cb, delay) {
var lastTime = Date.now();
return function () {
var nowTime = Date.now();
if (nowTime - lastTime > delay) {
cb();
lastTime = nowTime;
}
}
}
可以看下效果
查看链接
知道原理之后,想要使用,现在很多库都有这个功能
- jquery 插件 jQuery throttle / debounce
- Underscore 库 _.throttle 和 _.debounce
- lodash 库 _.debounce 和 _.throttle
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。