在前端开发中有一部分用户行为会频繁的触发事件执行,而对于DOM的操作、资源加载等耗费性能的处理,很可能会导致界面卡顿,甚至浏览器崩溃。函数的节流和防抖都是为了限制函数的执行频次,以优化函数触发频率过高导致的响应速度跟不上触发频率,防止短时间内频繁触发同一事件而出现延迟、假死获卡顿的现象。
1. 防抖
1.1 概念
防抖就是指连续触发事件但是在设定的一段时间内只执行最后一次,例如设定1000毫秒执行,当你触发事件了,他会在1000毫秒后执行,但是在还剩500毫秒的时候你又触发了事件,那就会重新开始1000毫秒之后再执行。好像手机一直玩就不息屏,隔一分钟不玩了就息屏。
单位时间内,频繁触发事件,只执行最后一次
1.2 场景
搜索框搜索输入、文本编辑器实时保存
1.3 代码实现思路
利用定时器,每次触发先清掉以前的定时器。
//搜索案例
//<input type="text" id="search">
let search = document.getElementById("search");
let timer = null;
search.oninput = function () {
// 清除前面的定时器
if (timer !== null) {
clearTimeout(timer)
}
// 保留最后一次定时器
timer = setTimeout(() => {
console.log(this.value);
}, 1000);
}
使用闭包,优化代码
let search = document.getElementById("search");
search.oninput = debounce(function(){
console.log(this.value);
},1000)
function debounce(fn,delay) {
let timer = null;
return function () {
// 清除前面的定时器
if (timer !== null) {
clearTimeout(timer)
}
// 保留最后一次定时器
timer = setTimeout(() => {
fn.call(this)
}, delay);
}
}
2. 节流
2.1 概念
就是指连续触发事件但是在设定的一段时间内只执行一次函数。例如:设定1000毫秒执行,那你在1000毫秒内触发多次,也只在1000毫秒后执行一次。就像公交车一样,不是来一个乘客就发一趟车,而是十分钟发一趟车。
单位时间内,频繁触发,只执行一次
2.2 场景
高频事件:快速点击、鼠标滑动、resize事件、scroll事件
下拉加载:
2.3 代码实现思路
利用定时器,等定时器执行完毕,才能开始定时器
//下拉加载更多
window.onscroll = throttle(function () {
console.log("加载了一页!!!");
},1000)
function throttle(fn, delay) {
let timer = true;
return function () {
if (timer) {
setTimeout(() => {
fn.call(this)
timer = true;
}, delay);
}
timer = false;
}
}
3. lodash库
开发中一般使用lodash库,利用里面的防抖(debounce)和节流(throttle)。
// 防抖:单位时间,频繁出发,执行最后一次
search.oninput = _.debounce(function () {
console.log(this.value);
}, 1000)
// 节流:单位时间,频繁出发,只执行一次
window.onscroll = _.throttle(function () {
console.log("加载下一页!!");
}, 1000, {
trailing: true,
leading: false
})