李南江JavaScript程序设计

如何理解debounce和throttle?

2019-01-09  本文已影响35人  趁你还年轻233

前端工程师们都听过看起来很高级的词,节流和防抖,其实节流就是debounce,防抖就是throttle,其实这个也属于前端性能优化的一部分。

在做远程搜索时,如果每输入1个字就调用1次接口,就会频繁查询数据库,假设我们的查询是"一二三四五",不考虑用户输入错误的情况,至少会请求5次。

有没有一种方法,可以隔个几百毫秒再去查询呢?

有,可以为函数设置一个setTimeout函数,相当于定时调用接口,这种方法是低效的,也是非常愚蠢的,需要控制开关定时器,一旦搜索功能多了,就更蠢了。

有没有更加高级的做法,用户输入完成后,停顿了几百毫秒再去查询呢?

有,debounce就是做这个事情的,lodash从0.1.0就支持了这个方法。

css-tricks的lodash debounce demo

<input type="text" class="autocomplete">
// 被debounce的函数,http请求,事件处理函数等等
function make_ajax_request(){
    // 这是一个调用后端api的方法
}
// 监听事件并且调用lodash的debounce方法
$('.autocomplete').on('keydown',
     _.debounce(make_ajax_request, 1300));
});

demo地址:https://codepen.io/dcorb/embed/mVGVOL?height=257&theme-id=1&slug-hash=mVGVOL&default-tab=result&user=dcorb

vue项目中的lodash debounce demo

<template>
  <input @input="debounceHandleInput"/>
</template>

<script>
import _ from 'lodash';

export default {
  name: 'debounce',
  data() {
    return {
      starTime: 0,
      endTime: 0,
      delay: 1000,
    };
  },
  computed: {
    debounceHandleInput() {
      return _.debounce(this.handleInput, this.delay);
    },
  },
  methods: {
    handleInput(e) {
      console.log(`debounce wait时间为${this.delay}ms`);
      console.log('触发了input事件', e.target.value);
      this.startTime = new Date().getTime();
      this.remoteMethod();
    },
    remoteMethod() {
      setTimeout(() => {
        const result = `后端请求已完成!`;
        this.endTime = new Date().getTime();
        const costTime = this.endTime - this.startTime;
        console.log(result);
        console.log(`耗时${costTime}毫秒`);
      }, 2000);
    },
  },
};
</script>

打印结果:
debounce wait时间为1000ms
触发了input事件 13131
后端请求已完成!
耗时2000毫秒

在1000ms时间范围内触发,仅仅调用一次remoteMethod,也就是仅仅调用一次后端接口,达到我们的预期效果。

debounce适用场景

在做滚动加载时,如果用户滚动的幅度过大,会导致加载的内容过多,相当于水的流量没有控制,一瞬间大量的水量迸发而出,从而所看到的延后好几个与预期的下一个不符的情况

有,throttle就是做这个事情的,lodash从0.1.0也支持了这个方法。

具体demo就不写了,因为throttle常用于连续事件的事件处理函数

可以参考 https://css-tricks.com/the-difference-between-throttling-and-debouncing/ 文章最后的demo,其中的throttle在scroll上的运用,就是throttle的正确打开方式。

image

throttle适用场景

debounce和throttle的对比

地址:http://demo.nimius.net/debounce_throttle/
图片:

image

通过在canvas上连续触发mousemove事件我们发现:

努力成为一个不掉队的前端工程师!

上一篇下一篇

猜你喜欢

热点阅读