【前端帮帮忙】第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图:

【前端帮帮忙】第7期 关于节流(throttle)和防抖(debounce)的理解

可以看到,函数执行了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次。

【前端帮帮忙】第7期 关于节流(throttle)和防抖(debounce)的理解

通过一个定时器,我们控制函数每隔500毫秒再执行一次,大大降低了执行频率,从而提升性能。

节流概念理解

节流跟防抖,它们既有相似之处但又有所不同,很容易混淆。这里通过比喻来加深理解,先来说说节流。

节流的概念可以想象一下水坝,你建了水坝在河道中,不能让水流动不了,你只能让水流慢些。换言之,你不能让用户的方法都不执行。(个人比较喜欢这个比喻,因为它很形象的说出了跟防抖的区别。)

防抖

控制函数在n秒内只能执行一次,如果用户在n秒内重复的触发事件,则重新计时且函数不会被执行,只有等到用户不再触发事件的时候才去执行一次。

作用跟 节流 类似,也是为了防止用户高频率的触发事件所引发的性能问题。

防抖概念理解

可以想象一下做电梯,当有人进入电梯(触发事件),那电梯将在10秒后出发(执行事件),这时如果又有人进入电梯了(在10秒内再次触发了事件),我们又得重新等10秒才能触发(重新计时)。

示例

有个文本框让用户填写用户名,当用户输入字符时,我们需要实时发请求到后台去验证用户名是否有重复的。实际上,在加入防抖机制前,用户输入 helloworld 后,我们已经发送了10次请求了,很显然是不可取的。

看代码:

let obj = document.querySelector('#testInput');  // 获取文本输入框
let _count = 0;

obj.onkeyup = function () {
  _count++;
  console.log('执行次数:' + _count);
}
复制代码
【前端帮帮忙】第7期 关于节流(throttle)和防抖(debounce)的理解

我们来给代码加入防抖机制:

我们只能假设用户在停顿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);
}
复制代码
【前端帮帮忙】第7期 关于节流(throttle)和防抖(debounce)的理解

通过动图,可以看到,当我一直输入的时候,事件是不会被触发的,直到我停止输入才会触发一次。

实现思路:我们把目标代码放入到一个定时器里,如果事件被频繁的触发,目标代码将不会被执行。为什么不执行呢,因为我们前面加了 clearTimeout 。相当于中途不断的有人进入电梯,电梯又得重新倒计时10秒才会启动一样,直到用户没再输入了(没人再进入电梯了),这时候目标代码才会按照我们设定的时间再去执行一次(电梯才会启动)。

节流和防抖的区别

  • 节流:目标代码会按照我们设定的时间间隔即每隔n秒就执行一次
  • 防抖:在用户不触发事件时,才去执行目标代码,并且抑制了本来在事件中要执行的动作;当事件被一直触发的情况下,目标代码有可能不会被执行
  • 函数节流会用在比 input , keyup 更频繁触发的事件中,如 resize , touchmove , mousemove , scroll节流 会强制函数以固定的速率执行。因此这个方法比较适合应用于动画相关的场景。

最后

感谢您的阅读,希望对你有所帮助。文中如果有描述不当的地方,烦请指正,感激不尽。 另外文中所演示的代码仅用来测试使用,并不适合用在实际开发中,实际开发可以使用 Lodash 库中的 节流防抖 方法,这里就不贴代码了,毕竟考虑的比较全面哈。

Lodash 库的地址:

节流: www.lodashjs.com/docs/4.17.5…

防抖: www.lodashjs.com/docs/4.17.5…


以上所述就是小编给大家介绍的《【前端帮帮忙】第7期 关于节流(throttle)和防抖(debounce)的理解》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

算法设计手册

算法设计手册

斯基恩纳 / 清华大学出版社 / 2009-9 / 69.00元

《算法设计手册(第2版)》是算法设计畅销书的最新版本,是设计实用且高效算法的最全面指导书。《算法设计手册(第2版)》揭密了算法的设计与分析,以简单易懂的写作风格,介绍了各种算法技术,着重强调了算法分析,全书包括两大部分,“技术”部分介绍了设计和分析计算机算法的各种方法,“资源”部分给出了大量的参考资源,以及算法实现的各种资源,此外,在作者的个人网址http://www.CS.sunysb.edu/......一起来看看 《算法设计手册》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具