共计 2138 个字符,预计需要花费 6 分钟才能阅读完成。
前端工程师们都听过看起来很高级的词,节流和防抖,其实节流就是 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/embe…
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 适用场景
Debouncing a input event handler(this example explain this use case)
Debouncing a resize event handler
Debouncing a save function in an autosave feature
在做滚动加载时,如果用户滚动的幅度过大,会导致加载的内容过多,相当于水的流量没有控制,一瞬间大量的水量迸发而出,从而所看到的延后好几个与预期的下一个不符的情况
当水流超过阀值时,最多释放出阀值量的水;水流小于阀值时,一切正常。有没有一种办法去控制水流的大小?
有,throttle 就是做这个事情的,lodash 从 0.1.0 也支持了这个方法。
具体 demo 就不写了,因为 throttle 常用于连续事件的事件处理函数。
可以参考 https://css-tricks.com/the-di… 文章最后的 demo,其中的 throttle 在 scroll 上的运用,就是 throttle 的正确打开方式。
throttle 适用场景
Throttling a scroll event in infinite scroll(demo case)
Throttling a mousemove/touchmove event handler in canvas
debounce 和 throttle 的对比
地址:http://demo.nimius.net/deboun… 图片:
通过在 canvas 上连续触发 mousemove 事件我们发现:
debounce 只有当连续事件停止后的一小段时间后再触发一次,连续事件结束后可能只触发一次
throttle 会在连续事件的过程中,每隔一段时间至少触发一次,连续事件结束后触发不止一次
努力成为一个不掉队的前端工程师!