一、防抖和节流主要解决了什么问题
带来的问题:
在短时间内事件如果被高频的触发,会不断的调用绑定在事件上的回调函数,极大的浪费资源,降低前端性能。
主要解决:
本质上是优化高频率执行代码的一种手段。函数防抖和函数节流就是为了限制函数的执行频次,以优化函数触发频率过高导致响应速度跟不上触发频率,出现延迟、假死或卡顿的现象。
二、定义
防抖:n 秒后再执行该事件,若在 n 秒内重复触发,则重新计时。
节流:n 秒内只执行一次,若在 n 秒内重复触发,只有一次生效。(在指定时间间隔内,只会执行一次任务)
三、防抖
1. 好处
能够保证用户在频繁触发某些事件的时候,不会频繁的执行回调,只会执行一次。
2. 图解
3. 应用场景
用户在输入框连续输入一串字符时,可以通过防抖策略,只在输入完成后,才执行查询的请求,这样可以有效减少请求次数,节约请求资源。
4. 实现思路
<body>
<input type="text" oninput="inputValue()">
<script>
let input = document.querySelector('input')
input.oninput = debounce(inputValue, 1000)
// input事件(需要防抖的函数)
function inputValue(e) {
let value = e.target.value
console.log(value)
}
// 防抖函数
function debounce(fn, delay) {
let timer = null
return function() {
if(timer !== null) {
clearTimeout(timer)
}
timer = setTimeout(() => {
fn.apply(this, arguments) // 这里使用了apply方法给函数传参
timer = null
}, delay)
}
}
</script>
</body>
四、节流
1. 好处
可以减少一段时间内事件的触发频率。
2. 图解
3. 应用场景
- 鼠标连续不断地触发某事件(如点击),只在规定时间内触发一次。
- 懒加载时要监听计算滚动条的位置,但不必每次滑动都触发,可以降低计算的频率,而不必去浪费CPU资源。
4. 节流阀的概念
- 节流阀为空,表示可以执行下一次操作;不为空,表示不能使用下次操作
- 当前操作执行完之后要将节流阀重置为空,表示可以执行下次操作
- 每次执行操作之前,先判断节流阀是否为空
5. 实现思路
<body>
<button onclick="btnClick()">按钮</button>
<script>
let btn = document.querySelector('button')
btn.onclick = throttle(btnClick, 1000)
// 点击事件(需要节流的函数)
function btnClick() {
console.log("点击了")
}
// 节流函数
function throttle(fn, delay) {
let flag = true
return function() {
if(flag) {
flag = false
setTimeout(() => {
fn.apply(this) // 这里也可以使用call(this)
flag = true
}, delay)
}
}
}
</script>
</body>