一、是什么
本质上是优化高频率执行代码的一种手段
如:浏览器的 resize
、scroll
、keypress
、mousemove
等事件在触发时,会不断地调用绑定在事件上的回调函数,极大地浪费资源,降低前端性能
为了优化体验,需要对这类事件进行调用次数的限制,对此我们就可以采用 防抖(debounce) 和 节流(throttle) 的方式来减少调用频率
二. 区别以及共同点
JS 防抖与节流
共同点 | 区别 | 应用场景 | |
---|---|---|---|
防抖 debounce | 在事件频繁被触发的时候 | 只执行最后一次 | input输入 |
节流 throttle | 减少事件执行的次数 | 有规律的执行 | 拖拽,Scroll |
三. 代码实现
防抖方法的实现
let input = document.querySelector('input')
input.addEventListener('keyup', debounce(function () {
console.log(input.value, '向后台取数据');
})
)
// 手写一个防抖函数来解决重复请求后台服务器的问题
function debounce(fn) {
let timer = null;
return function () {
if (timer) clearTimeout(timer)
timer = setTimeout(() => {
fn.apply(this, arguments)
timer = null;
}, 1000)
}
}
上面代码的意思是:
找到页面中第一个 input
元素,添加一个 "keyup" 事件监听器
,当用户输入内容时,使用防抖函数 debounce
来限制事件的触发频率,每次事件最多只被触发一次
。
防抖函数返回一个新函数
,该函数会在一定时间内(这里是 1000 毫秒)不执行,在该时间内如果再次触发了该事件,会清除之前的计时器
并重新设置计时器。当计时器结束后,才会执行传入的函数并向后台服务器请求数据,同时将 input 元素的值作为参数进行输出。
这样可以防止用户输入过快或者频率过高
,导致向后台服务器发送重复的请求
。
节流函数代码的实现
let box = document.querySelector('.box')
box.addEventListener('drag', throttle(function (e) {
console.log(e.clientX);
}))
function throttle(fn) {
let timer = null;
return function () {
if (timer) return
timer = setTimeout(() => {
fn.apply(this, arguments)
timer = null
}, 100)
}
}
上面代码的意思:
找到页面中 class 为 "box"
的元素,添加一个 "drag" 鼠标拖拽
事件监听器,当用户拖动该元素时,使用节流函数 throttle
来限制事件的触发频率
,每100毫秒触发一次事件
,并在控制台输出鼠标的 x 坐标值。其中 throttle 函数返回一个新函数,该函数在 timer 计时器未结束时不会执行
,从而实现了事件的节流
。
四. 防抖效果图展示(前后对比)
没有加防抖函数之间 加了防抖函数之后
节流效果图展示(前后对比)
没有加节流函数之间
加了节流函数之后
五.总结
防抖函数的作用是在用户停止触发事件后,延迟一段时间再执行函数。这样可以避免频繁地执行一些计算量大或者请求量大的函数,比如自动保存、搜索建议等。
节流函数的作用是在一定时间间隔内,只执行一次函数。这样可以保证函数的执行速度不超过设定的频率,比如滚动事件、窗口大小调整等。
防抖和节流函数的好处是可以提高性能,减少资源消耗,优化用户体验。