前端性能优化利器——防抖与节流
一个图片,直观地了解防抖节流!
1、防抖
防抖?什么意思
防抖听起来比较生动形象哈,就是为了防止你抖,一不小心点了多次相同的事件,最后就只给你执行一次。注意:这只是我较为易懂的解释了一下这个防抖的意思,我相信屏幕前大佬们肯定不会手抖!
较为正经的解释就是:防抖是一种策略,它的目的是减少因用户频繁触发同一事件而造成的不必要的处理。
防抖的最常见的场景
防抖最常见的场景也是我们经常用到的浏览器的搜索建议。不知道你们有没有发现这个现象,我们想要在百度里面搜索一些内容,他下面会给我们推荐出相应的包含你输入字符的内容。
当然还有一些应用场景,例如调整窗口的大小,鼠标滚轮事件,图片懒加载等。
防抖的实现原理
防抖的核心思想是在连续触发的事件中,只有在最后一次事件发生后的一定时间间隔内没有新的事件触发时,才执行相应的处理函数。根据它的核心的思想,我们可以设置一个定时器和清除定时器来实现这个功能,具体的代码实现如下:
function debounce(func,delay){
return function(args){
clearTimeout(func.id) //清除定时器 如果注释的话还是那么多频次,只是每次推迟了
// 函数也是对象 id挂在func上,func是闭包中的自由变量
func.id = setTimeout(function(){
func(args)
},delay)
}
}
给大家解释一下这段代码的内容:这是我们定义一个实现防抖的函数,接受两个参数,一个为我们执行的事件函数,另一个参数就是我们定义的延迟的时间,这里利用了闭包这个思想。
clearTimeout(func.id)
这行代码的就是清除之前的定时器,要实现防抖,就是需要确保在一段连续触发的相同事件中取最后一次且经过delay时间后才触发。
func.id = setTimeout
这就是设置个定时器,经过delay的时候才会触发这个函数。
这样就实现了我们想要的防抖功能,因为每次事件触发都会重置定时器,而 func
只会在定时器最终未被清除的情况下执行。
防抖的演示
这里就举一个最简单的例子来实现查看防抖前和防抖后的效果,就是监听表单输入
这个演示我觉得就可以很明显的看出防抖的作用,没有防抖时,向输入框中输入一段字符串,他会监听到n次,但是使用防抖后,就只会执行一次,这就大大的减少了浏览器的开销,想想如果这不仅仅是个监听输入的事件,而是发送请求,或者调整dom结构呢,那这样的性能开销就减少了更多,体验也就更明显。这一刻,也许就明白了防抖的意义吧?
2、节流
由于防抖和节流的使用场景类似,所以我们很容易把防抖和节流搞混,我们同样也是通过最上面的那张图可以看出他们之间的区别。
节流是什么?
节流(Throttle)是一种常见的前端优化技术,用于限制函数的执行频率,确保函数在规定的时间间隔内最多只能执行一次。这个也还好理解,但是我觉得还是没有防抖生动形象。
节流的实现原理
节流的核心思想是在规定的时间间隔内,无论触发多少次事件,函数都只会执行一次。所以实现的最关键的地方就是检查时间,如果当前的时间小于上一次执行的时间加上延迟的时间,那就不执行。根据这一思想,我们实现代码如下:
const throttle = (func,delay) =>{
let last,deferTimer //闭包中的自由变量,表示上一次执行的时间,以及定时器
return (args)=>{
// 干掉触发
let now = +new Date();
if(last && now <last+delay){
clearTimeout(deferTimer)
deferTimer = setTimeout(()=>{
last = now
func(args)
},delay)
}else{
//需要让执行过段时间再来到此处
last = now // 第一次时间
func(args) // 先执行一次
}
}
}
if(last && now <last+delay)
判断当前时间与上一次执行的时间和延迟的时间大小,如果小于则清除掉事件的定时器,设置一个定时器确保最后一次的事件能够被执行。否则的话就允许执行。这个逻辑还是比较简单的。
演示效果
还是跟刚才一样演示一下节流的效果,让大家有个更清楚的认识。
总结
防抖和节流是我们前端性能优化的一大利器,它能够限制函数执行的频率,从而减少那些重复执行的函数,达到优化性能,提高用户体验的效果。要实现这两个利器,我们都要用到闭包,以及定时器和清除定时器。所以你们会了吗?
转载自:https://juejin.cn/post/7397278180656611369