本文共 2000 字,读完只需 8 分钟
上一篇文章讲了去抖函数,然后这一篇讲同样为了优化性能,降低事件处理频率的节流函数。
一、什么是节流?
节流函数(throttle)就是让事件处理函数(handler)在大于等于执行周期时才能执行,周期之内不执行,即事件一直被触发,那么事件将会按每小段固定时间一次的频率执行。
打个比方:王者荣耀、英雄联盟、植物大战僵尸游戏中,技能的冷却时间,技能的冷却过程中,是无法使用技能的,只能等冷却时间到之后才能执行。
那什么样的场景能用到节流函数呢?
比如:- 页面滚动和改变大小时需要进行业务处理,比如判断是否滑到底部,然后进行懒加载数据。
- 按钮被高频率地点击时,比如游戏和抢购网站。
我们通过一个简单的示意来理解:
节流函数可以用时间戳和定时器两种方式进行处理。
二、时间戳方式实现
正在滑动:0
看时间戳实现版本的效果:
三、定时器方式实现
正在滑动: 0
看看定时器版实现版本的效果:
三、时间戳和定时器的对比分析
对比时间戳和定时器两种方式,效果上的区别主要在于:
事件戳方式会立即执行,定时器会在事件触发后延迟执行,而且事件停止触发后还会再延迟执行一次。
具体选择哪种方式取决于使用场景。underscore 把这两类场景用 leading 和 trailing 进行了表示。
四、兼容两种方式, underscore 源码实现
underscore 的源码中就同时实现了时间戳和定时器实现方式,在调用时可以自由选择要不要在间隔时间开始时(leading)执行,或是间隔时间结束后(trailing)执行。
具体看伪代码和示意图:
正在滑动: 0
下面是我画的示意图:
大致总结一下代码对事件处理逻辑的影响:- 如果 leading 为真,那么绿色意味着间隔时间的开始会立即执行,第一次触发也会立即执行。
- 如果 trailing 为真,那么从蓝紫色的竖细线后的剩余事件,会跑一个定时器,定时器在时间间隔结束时再执行一次事件处理函数。
- 如果 leading 不为真,那么第一次事件触发不会立即执行。
- 如果 trailing 不为真,最后一次事件触发后,不然再执行一次事件处理函数。
节流和去抖的常见场景
- 输入框打字输入完后才开始异步请求数据校验内容:去抖
- 下拉滚动条判断是否到底部,进行懒加载数据:去抖和节流都可以,判断是否到底的方式不同
- 活动网站、游戏网站,按钮被疯狂点击:节流
六、总结
去抖和节流函数都是为了降低高频率事件触发的事件处理频率,从而优化网页中大量重绘重排带来的性能问题。
其区别在于去抖会在高频率事件触发时,只执行一次,节流会在满足间隔时间后执行一次。去抖的 immediate,节流中的 leading, trailing 都是为了尽可能满足这类工具函数的不同使用场景。