【前端帮帮忙】第7期 关于节流(throttle)和防抖(debounce)的理解
栏目: JavaScript · 发布时间: 5年前
内容简介:防止用户高频率的触发事件,刚好这个事件又需要处理大量的计算和渲染而带来的性能问题。这边我们以比如有这样一个场景:我们需要判断浏览器滚动条滚动到底部的时候去动态加载一些数据,可能我们直接就会写上以下的代码:
防止用户高频率的触发事件,刚好这个事件又需要处理大量的计算和渲染而带来的性能问题。
应用场景
- onscroll
- onresize
- mousemove
- touchmove
- ...
示例
这边我们以 onscroll
来写个例子,加深理解。
比如有这样一个场景:我们需要判断浏览器滚动条滚动到底部的时候去动态加载一些数据,可能我们直接就会写上以下的代码:
let obj = document.querySelector('.throttle-test'); let _count = 0; obj.onscroll = function () { // 假设已经滚动到底部了,我们给_count加1。 _count++; console.log('执行次数:' + _count); } 复制代码
我们来看下浏览器的打印结果,看以下gif图:
可以看到,函数执行了20次,很显然这并不是我们想要的,因为 onscroll
事件并不会等你滚动到底部了再去触发事件,而是会不间断的触发,这就很容易引发一些性能问题,这时候就需要用到节流了。
我们把代码做下修改:
let obj = document.querySelector('.throttle-test'); let _count = 0; let _canRun = true; obj.onscroll = function () { if (!_canRun) { return false; } _canRun = false; setTimeout(function () { // 假设已经滚动到底部了,我们给_count加1。 _count++; console.log('执行次数:'+_count); _canRun = true; }, 500); } 复制代码
通过以下gif图,我们可以看到,函数最终只执行了2次。
通过一个定时器,我们控制函数每隔500毫秒再执行一次,大大降低了执行频率,从而提升性能。
节流概念理解
节流跟防抖,它们既有相似之处但又有所不同,很容易混淆。这里通过比喻来加深理解,先来说说节流。
节流的概念可以想象一下水坝,你建了水坝在河道中,不能让水流动不了,你只能让水流慢些。换言之,你不能让用户的方法都不执行。(个人比较喜欢这个比喻,因为它很形象的说出了跟防抖的区别。)
防抖
控制函数在n秒内只能执行一次,如果用户在n秒内重复的触发事件,则重新计时且函数不会被执行,只有等到用户不再触发事件的时候才去执行一次。
作用跟 节流
类似,也是为了防止用户高频率的触发事件所引发的性能问题。
防抖概念理解
可以想象一下做电梯,当有人进入电梯(触发事件),那电梯将在10秒后出发(执行事件),这时如果又有人进入电梯了(在10秒内再次触发了事件),我们又得重新等10秒才能触发(重新计时)。
示例
有个文本框让用户填写用户名,当用户输入字符时,我们需要实时发请求到后台去验证用户名是否有重复的。实际上,在加入防抖机制前,用户输入 helloworld
后,我们已经发送了10次请求了,很显然是不可取的。
看代码:
let obj = document.querySelector('#testInput'); // 获取文本输入框 let _count = 0; obj.onkeyup = function () { _count++; console.log('执行次数:' + _count); } 复制代码
我们来给代码加入防抖机制:
我们只能假设用户在停顿n秒内没有再触发事件,我们就判定用户已经输入完成了,这时再发送请求。
看代码:
let obj = document.querySelector('#testInput'); let timer = null; let _count = 0; obj.onkeyup = function () { clearTimeout(timer); // 清除定时器,重新计时 timer = setTimeout(function () { _count++; console.log('执行次数:'+_count); }, 800); } 复制代码
通过动图,可以看到,当我一直输入的时候,事件是不会被触发的,直到我停止输入才会触发一次。
实现思路:我们把目标代码放入到一个定时器里,如果事件被频繁的触发,目标代码将不会被执行。为什么不执行呢,因为我们前面加了 clearTimeout
。相当于中途不断的有人进入电梯,电梯又得重新倒计时10秒才会启动一样,直到用户没再输入了(没人再进入电梯了),这时候目标代码才会按照我们设定的时间再去执行一次(电梯才会启动)。
节流和防抖的区别
- 节流:目标代码会按照我们设定的时间间隔即每隔n秒就执行一次
- 防抖:在用户不触发事件时,才去执行目标代码,并且抑制了本来在事件中要执行的动作;当事件被一直触发的情况下,目标代码有可能不会被执行
- 函数节流会用在比
input
,keyup
更频繁触发的事件中,如resize
,touchmove
,mousemove
,scroll
。节流
会强制函数以固定的速率执行。因此这个方法比较适合应用于动画相关的场景。
最后
感谢您的阅读,希望对你有所帮助。文中如果有描述不当的地方,烦请指正,感激不尽。 另外文中所演示的代码仅用来测试使用,并不适合用在实际开发中,实际开发可以使用 Lodash
库中的 节流
和 防抖
方法,这里就不贴代码了,毕竟考虑的比较全面哈。
Lodash
库的地址:
以上所述就是小编给大家介绍的《【前端帮帮忙】第7期 关于节流(throttle)和防抖(debounce)的理解》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。