防抖和节流属于前端很常见而且很常用的性能优化知识了,使用频率非常高,所有有必要掌握。
从输入框的例子说起
很多输入框都会添加oninput事件,在输入后执行
function input (e) {
console.log('你输入了:' + e.value);
}
但是如果你运行输入的时候,会发现这个方法的执行频率太高了,没输入和删除一个字符都会执行一次
这样会消耗很多资源,如果有网络请求的话,那会向后台请求多次,消耗网络资源和后台资源,那这里就有优化的空间了,那怎么样做到让用户输入完了以后才执行方法呢?这时候防抖出来了。
防抖(debounce)
防抖:如果短时间内大量触发同一事件,只会执行一次函数。
实现:有新事件触发,清除旧定时器,重置新定时器
function debounce(fn, delay) {
let timer
return function (...args) {
if (timer) {
clearTimeout(timer)
}
timer = setTimeout(() => {
fn.apply(this, args)
}, delay)
}
}
function input(e) {
console.log("你输入了:"+e.data);
}
const debounceTask = debounce(input, 1000)
var node=document.getElementById("myInput")
node.addEventListener('input',debounceTask)
上面的代码就是在输入完1秒后才执行方法,1秒内多次触发都会把上次的事件给覆盖掉,这就是把防抖给实现了
节流(throttle)
现在更换一种场景,如果一个实现按钮在n秒内只能点击一次,这样要怎么做呢?
这时候就需要用到我们的节流
节流:固定时间内,只触发一次,若有新事件触发,不执行。
实现:第一次执行后记录下当前时间,如果还在n秒内就不往下执行
function throttle(fn, delay) {
let last = 0 // 上次触发时间
return (...args) => {
const now = Date.now()
if (now - last > delay) {
last = now
fn.apply(this, args)
}
}
}
function myClick() {
console.log('执行了'+new Date())
}
const throttleTask = throttle(myClick, 2000)
var throttleNode=document.getElementById("mybutton")
throttleNode.addEventListener('click',throttleTask)
以上代码实现了连续多次点击按钮,每2秒才执行一次方法。
以上就是防抖和节流,是两种比较常见的优化手段,防抖和节流各有优点,应该结合不同场景来判断使用哪个。