上一篇文章, 我们在阿飞的帮助下, 一起学习了防抖(Debounce)这一概念
既然谈到了防抖, 节流(Throttle)自然也是不能放过的, 在本篇文章中, 我们将一起探讨节流
概念理解
依然在打工的阿飞
继续请出我们的朋友阿飞, 他依然在餐厅打工当服务生. 虽然点单的流程已经进行了防抖处理, 但一天到晚的工作还是让他累得不行
于是他决定: 一周只打五天工
当周一早晨的闹钟响起, 阿飞不得不起床去餐厅, 因为这周连一天都还没有工作; 当周四早晨的闹钟响起, 阿飞依然得离开温暖的被窝, 因为这周还需要工作两天
可当周六早晨的闹钟响起, 阿飞可以把闹钟关掉, 翻个身继续美梦, 因为我们的朋友这周已经工作五天了, 今天是他的休息日
一周工作满五天后休息两天, 劳逸结合, 这样阿飞无论是在工作中还是生活中都能够保持精力充沛
类比
我们在前端程序设计中也可以像阿飞安排工作一样, 把一些函数在单位时间内被执行的次数固定, 从而降低相关资源的负荷, 提升性能表现
一种实现
直接从节流的概念出发, 我们很容易想到: 可以引入一个标记来记录函数在当前单位时间内是否已经被执行过
若未执行过, 则立即执行相应函数, 并将该标记设置为已执行过, 且直到下一个单位时间才刷新标记, 从而控制函数在单位时间被执行的次数
/**
* 为已有函数设置节流
*
* @param {Function} func 将设置节流的函数
* @param {number} limit 单位时间
* @return {Function} 设置节流后的函数
*/
const throttle = (func, limit) => {
// 标记单位时间内是否已经执行对应函数
let inThrottle;
return function(...args) {
// 若标记显示当前单位时间内未执行, 则执行对应函数并设置标记
if (!inThrottle) {
const context = this;
Reflect.apply(func, context, args);
inThrottle = true;
setTimeout(() => inThrottle = false, limit);
}
}
}
测试
我们可以基于 onscroll 来粗略展示一下节流的效果
-
HTML<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>throttle</title> </head> <body> <div id="demo" style="height: 1000px"></div> <script src="./throttle.js"></script> </body> </html> -
JavaScript/** * 为已有函数设置节流 * * @param {Function} func 将设置节流的函数 * @param {number} limit 单位时间 * @return {Function} 设置节流后的函数 */ const throttle = (func, limit) => { // 标记单位时间内是否已经执行对应函数 let inThrottle; return function (...args) { // 若标记显示当前单位时间内未执行, 则执行对应函数并设置标记 if (!inThrottle) { const context = this; Reflect.apply(func, context, args); inThrottle = true; setTimeout(() => inThrottle = false, limit); } } } const demo = document.getElementById("demo"); let COUNT = 0; function count() { demo.innerHTML += (`上下滑动对应回调函数被执行了${++COUNT}次<br>`); } // 添加节流前 // window.onscroll = count; // 添加节流后 window.onscroll = throttle(count, 3000); -
添加节流前
-
添加节流后
从上述两张 Gif 图中, 我们可以看出: 在添加节流之前,
onscroll 对应的函数将会随着页面的上下滑动被执行多次;
而在添加节流之后, 对应函数在单位时间内只会被执行一次, 直到下一个单位时间才会被再次执行
总结
通过节流, 我们可以主动地控制相关函数的执行频率, 从而避免事件在短时间内大量触发造成页面卡顿
除了在上文中提到的 onscroll, 还有按钮重复点击和 touchmove 等都可以使用节流
以上是我对节流(Throttle)的理解, 如果文章中存在问题或是大家有更好的理解, 欢迎大家指出和交流:)