一、简介
JavaScript中的防抖与节流是两种优化高频执行函数(如:click、keydown、mousemove、resize事件等)的方法,主要用于控制函数执行的频率,从而减少不必要的资源消耗,提高页面性能。
二、防抖(Debounce)
概念:当事件被连续触发时,只有在最后一次触发事件后的延迟时间内没有再次触发,才会执行目标函数(即:事件被触发后,不会立即执行该事件的回调函数,若在该事件的延迟时间内,没有再触发该事件,则执行该事件的回调函数)
例:假设一个事件的延迟时间是3秒,当触发了该事件,则它的回调函数会在3秒后执行;
在这延迟的3秒期间,如果又触发了该事件,则会重新开始计时3秒钟; 如果又触发,就再重新计时,再触发,再重新计时…;
直到距离事件的触发时间(延迟时间),大于3秒钟,才会执行该事件的回调函数;
// 防抖函数
export function debounce(fn, wait){
let timer = null
return function(...args) {
if (timer) clearTimeout(timer)
timer = setTimeout(() => fn.apply(this, args), wait)
}
}
三、节流(Throttle)
概念:当事件被连续触发时,在设定的一段时间内,只执行一次该事件的回调函数(即:执行一次事件的回调函数后,等到间隔时间结束,若再触发该事件,才会再执行该事件的回调函数)
例:假设一个事件的间隔时间是3秒,当第一次触发了该事件,会执行该事件的回调函数, 3秒间隔内,再触发该事件,并不会再执行该事件的回调函数;
直到3秒钟过后,再触发该事件,才会再执行该事件的回调函数;
// 节流函数
export function throttle(fn, delay){
let lastCall = 0
return function(...args) {
const now = new Date().getTime()
if (now - lastCall < delay) return
lastCall = now
fn.apply(this, args)
}
}
注:还可以使用lodash库的debounce, throttle函数
// import { debounce, throttle } from '@/utils/tools'
import { debounce, throttle } from 'lodash'
......
methods: {
// 节流
handle1: throttle(function () {
console.log(Math.random())
}, 3000),
// 防抖
handle: debounce(function () {
console.log(Math.random())
}, 2000)
},
mounted() {
// 传递函数引用,而非调用结果
window.addEventListener('resize', this.handle)
window.addEventListener('scroll', this.handle1)
},
beforeDestroy() {
// 记得移除监听器,避免内存泄漏
window.removeEventListener('resize', this.handle)
window.removeEventListener('scroll', this.handle1)
}