当前位置: 代码迷 >> 综合 >> 性能优化-防抖(debounce)和 节流(throttle)
  详细解决方案

性能优化-防抖(debounce)和 节流(throttle)

热度:14   发布时间:2023-12-23 14:23:43.0

防抖debounce

+.监听一个输入框,文字变化后触发change事件

+.如果没有用防抖,直接用keyup事件,则会频发change事件,影响性能

+.但是采用防抖:用户输入结束或者暂停时,彩绘触发change事件

debounce 一段时间内连续的函数调用,只允许其函数执行一次。原理是,维护一个定时器,只有定时器结束才可以继续触发事件。

未封装代码代码(用于巩固理解):

let timer = null
let oInput = document.getElementById('input')
oInput.addEventListener('keyup', function(){if(timer){clearTimeout(timer)}timer = setTimeout(function(){console.log(oInput.value)}, 500)
})

 封装好的代码:

// setTimeout是过了一段事件后触发函数体
// 防抖就是说,比如当在文本框内输入内容,如果在时间没有到之前继续输入文字内容,那么最后的时间将是最后一个文字输入时间一直到结束
function debounce(fn, delay=500){// 给闭包使用let timer = nullreturn function(){if(timer){clearTimeout(timer)}// 采用箭头函数,如果采用ES5的写法,则this会指向Windowtimer = setTimeout(() => {// 指向fn这个函数,最好能这么写,比如传了event上面那个就会报错fn.apply(this, arguments)}, delay)}
}

代码测试:(在一段时间(600ms)内连续触发debounce函数,但是debounce函数只会执行一次,当用户不在输入文字时,并且在输入最后一次文字等待600ms结束才会触发funtion(){console.log(oInput.value}),并且取消定时器

let oInput = document.getElementById('input')
// 要知道传进去什么,然后返回什么
oInput.addEventListener('keyup', debounce(function(){console.log(oInput.value)
}, 600))

节流throttle

+.拖拽一个元素时,要随时拿到该元素被拖拽的位置

+.直接用drag事件,则会频繁触发,很容用导致卡顿

+.但是使用节流,无论拖拽速度多块,都会每隔100ms触发一次

throttle:一段时间内的函数调用,保证事件一定会被执行一次。节流可以保证在一段时间内函数必定会触发一次。

未封装代码(用于巩固):

const oDiv1 = document.getElementById('div1')
let timer = null
oDiv1.addEventListener('drag', function(e){if(timer) {return false//事件停止执行并跳出函数}// timer也可以是执行的次数timer = setTimeout(function () {// console.log(timer)console.log(e.offsetX, e.offsetY)// 因为timer为null,这个定时器才能持续运行timer = null// 因为是null,所以继续执行这个计时器}, 500)// 500秒后执行函数体,此时timer有值了,如果此时停止滑动,则执行判断语句
})

封装后的代码:

// 节流就是说,在触发时候是没有的,只有规定的时间内才触发事件,然后想要触发时候触再进入到这个函数体
function throttle(fn, delay=100){let timer = nullreturn function(){// let _this = this// let arg = argumentsif(timer){return false}timer = setTimeout(() => {//要采用箭头函数,采用ES5写法则this会指向windowfn.apply(this, arguments)timer = null}, delay)}
}// test
const oDiv1 = document.getElementById('div1')
oDiv1.addEventListener('drag', throttle(function (e) {console.log(e.offsetX, e.offsetY)
},1000))

测试

当在拖拽的时候,第一个100ms内是不会执行的的,到了100ms时候,执行上面箭头函数体一次,然后因为函数体的timer=null跳出return的函数体,最后重复下一个100ms的动作。

const oDiv1 = document.getElementById('div1')
oDiv1.addEventListener('drag', throttle(function (e) {console.log(e.offsetX, e.offsetY)
}, 100))

防抖的典型案例就是输入搜索:输入结束后n秒才进行搜索请求,n秒内又输入的内容,就重新计时。

节流的典型案例就是鼠标不断点击触发,规定在n秒内多次点击只有一次生效。