自用笔记:在浏览器DOM
事件里面,有一些事件会随着用户的操作不间断触发。比如:重新调整浏览器窗口大小(resize),浏览器页面滚动(scroll),鼠标移动(mousemove)。也就是说用户在触发这些浏览器操作的时候,如果脚本里面绑定了对应的事件处理方法,这个方法就不停的触发。
这并不是我们想要的,因为有的时候如果事件处理方法比较庞大,DOM 操作比如复杂,还不断的触发此类事件就会造成性能上的损失,导致用户体验下降(UI 反映慢、浏览器卡死等)。所以通常来讲我们会给相应事件添加延迟执行的逻辑。
debounce 与 throttle 是开发中常用的高阶函数,作用都是为了防止函数被高频调用,换句话说就是,用来控制某个函数在一定时间内执行多少次。
效果可视化
节流概念(Throttle)
定义: 如果一个函数持续的,频繁地触发,那么让它在一定的时间间隔后再触发。由于执行速度过快,并携带相邻数据相差不大,节流可以高效的优化执行效果。
应用场景
scroll、touchmove
节流实现
首次执行
通过时间比对,屏蔽多次提交,缺点:最后一个动作不会被触发
1 | function throttles(fn, wait = 100){ |
首次不执行
首次不执行,delay
时间内只执行滞后一次,通过判断timer
,进行判断延迟执行,预执行期间,去除其他执行请求。
1 | function throttles2(fn, delay = 100){ |
throttle
优点:成功的优化最后一针的位置
1 | function throttle (fn, wait = 250, options) { |
lodash
缺点无法获取参数,时间比对问题,属于首次执行的防抖的方法
1 | function throttle(fn, wait, options) { |
underscore
underscore提供了一系列函数式接口
1 | // 返回一个函数,只要这段时间被调戏就不会触发。函数停止后N毫秒触发, |
防抖概念(Debounce)
定义: 如果一个函数在一段时间间隔中,持续地触发,那么只在它结束后过一段时间只执行一次。
注意:这里的抖动停止表示你停止了触发这个函数,从这个时间点开始计算,当间隔时间等于你设定时间,才会执行里面的回调函数。如果你一直在触发这个函数并且两次触发间隔小于设定时间,则一定不会到回调函数那一步。·
应用场景
input验证、搜索联想、resize
防抖实现
思路:首次运行时把定时器赋值给一个变量,第二次执行时,如果间隔没超过定时器设定的时间则会清除掉定时器,重新设定定时器,依次反复,当我们停止下来时,没有执行清除定时器,超过一定时间后触发回调函数。
首次立即执行
首次执行,延后多次执行的最后一次时间。同上
1 | function throttle(fn, wait = 100, options) { |
延迟执行最后一个指令
1 | function debounce(fn, delay) { |
1 | function debounce (fn, wait, options) { |
1 | function debounce(fn, wait, options) { |
1 | function debounce(fn, delay = 200, atBegin = true) { |
1 | // 避免在滚动时过分的更新定位 |
1 | // 避免窗口在变动时出现昂贵的计算开销。 |