网站开发进阶(六十八)防抖节流
一、前言 - 为什么要防抖或节流
实现防抖或节流,主要基于以下目的:
及时查询时,减少服务器压力。
频繁执行
DOM
操作、资源加载等重行为,导致UI
停顿甚至浏览器崩溃。需求是以一定的频率执行后续的处理。
二、防抖 (debounce)
所谓防抖,就是把触发非常频繁的事件合并成一次去执行,以免把一次事件误认为多次。即在指定时间内只执行一次回调函数,如果在指定的时间内又触发了该事件,则回调函数的执行时间会基于此刻重新开始计算,敲键盘就是一个每天都会接触到的防抖操作。
想要了解一个概念,必先了解概念所应用的场景。在 JS
这个世界中,有哪些防抖的场景呢?
登录、发短信等按钮避免用户点击太快,以致于发送多次请求,需要防抖;
调整浏览器窗口大小时,
resize
次数过于频繁,造成计算过多,此时需要一次到位,就用到了防抖;提交表单;
文本编辑器实时保存,当无任何更改操作一秒后进行保存;
input 事件(当然也可以用节流,实现实时关键字查找);
实现原理:
只要触发,就会清除上一个计时器,又注册新的一个计时器。直到停止触发 wait 时间后,才会执行回调函数。
不断触发事件,就会不断重复这个过程,达到防止目标函数过于频繁调用的目的。
逻辑代码如下,可以看出来「防抖重在清零 clearTimeout(timer)」
三、节流 (throttle)
节流,顾名思义,控制水的流量。控制事件发生的频率,如控制为 1s 发生一次,甚至 1 分钟发生一次。与服务端(server
)及网关(gateway
)控制的限流 (Rate Limit
) 类似。
scroll
事件,每隔一秒计算一次位置信息等;浏览器播放事件,每隔一秒计算一次进度信息等;
input
框实时搜索并发送请求展示下拉列表,每隔一秒发送一次请求 (也可防抖实现);
实现原理:
只要触发,只会在当前计时器为空时,注册计时器。
不断触发事件,只会在固定的事件间隔触发。
有 2 种方式实现节流:setTimeout
与时间戳
。
setTimeout
时间戳
从以上逻辑代码可以看出来「节流重在开关锁 timer=null」
四、总结
防抖:防止抖动,单位时间内事件触发会被重置,避免事件误触发多次。
节流:控制流量,单位时间内事件只能触发一次,如果服务器端的限流即
Rate Limit
。
五、何时使用函数防抖、函数节流
使用函数防抖、函数节流可根据以下需求场景:
当我们只需要处理最后一次触发事件时,用函数防抖。如窗口大小值变化时,并不需要计算中间变化的过程,只需要窗口大小改变完成后的值。
当事件触发过于频繁,我们需要限制事件处理程序的调用频率时,用函数节流。
六、示例代码
版权声明: 本文为 InfoQ 作者【No Silver Bullet】的原创文章。
原文链接:【http://xie.infoq.cn/article/a1a910a9188f38b3fcac5be43】。文章转载请联系作者。
评论