JS中的节流和防抖

四糸乃赛高 Lv.5 冰封大地
43 2021/6/30笔记

在看别人的代码时在注释中发现了没听过的词汇,防抖,然后就去查了一下,总结自己的理解。

防抖(debounce):

效果:短时间内大量触发同一事件,最后只会执行一次函数。

用现实中的场景举例,在电梯外部按下按钮,电梯会在当前楼层停留一段时候后才往下走,如果在外部重复按下按钮,电梯就会一直停留在当前楼层。

可能需要用上的场景:scroll、mousemove、keydown等高频触发的事件,如果频繁触发事件绑定的函数,可能会造成页面卡顿等问题。

常见应用场景:(1)window的 resize 和 scroll 事件; 如:滚动到页面底部加载更多,稍微滚动一下就会触发n多次scroll事件,如果每次触发scroll事件的时候都去判断一次是否已经滚动到了页面底部,无疑会造成资源的浪费。此时若使用js节流,每隔一定的时间(如500ms)进行一次判断,间隔期间只能有一次触发判断,既节省了资源,也不会影响用户体验。(2)文字输入时的 keyup 事件; 如:输入搜索关键词的时候,进行自动完成或者自动联想。同理,这种情况下用户每敲击一次键盘就会触发一次keyup事件,此时用户可能连一个字都没有输入完成==,此时可以使用js防抖,在用户停止输入的一段时间后(如500ms)触发判断,进行自动联想或者自动搜索;也可以使用js节流,每隔一段时间,进行一次判断的执行,既可以实现实时的自动联想,也不会出现过于频繁的请求。(3)元素拖拽、移动时的 mousemove 事件;

实现原理:使用闭包在内部封装一个定时器(setTimeout),然后延迟执行,当重复调用时清除定时器,重新计时。

实现代码:

/**
 * @description 防抖
 * @param {Function} fn 需要执行的函数
 * @param {Number} delay 延迟时间
 * @returns Function
 */
function debounce(fn,delay){
    let timer = null 
    return function() {
        if(timer){
            clearTimeout(timer) 
        }
        timer = setTimeout(fn,delay) 
    }
}

缺点:如果连续的调用间隔一直小于delay, 会造成长时间不触发.



节流(throttle)

效果:在规定时间内,只能触发一次函数。如果这个时间内触发多次函数,只有一次生效。

实现原理:使用闭包在内部定义定时器,定时器计时未完成时不执行函数。

使用setTimeou实现:

/**
 * @description 节流
 * @param {Function} fn 需要执行的函数
 * @param {Number} delay 延迟时间
 * @returns Function
 */
function throttle(fn,delay){
    let timer = null 
    return function() {
        if(!timer){
            timer = setTimeout(()=>{
                timer = null;
                fn()
            },delay)
        }
    }
}

使用时间戳实现:

/**
 * @description 节流
 * @param {Function} fn 需要执行的函数
 * @param {Number} delay 延迟时间
 * @returns Function
 */
 function throttle(fn, wait) {
    let previous = 0;
    return function() {
        let now = Date.now();
        if (now - previous > wait) {
            fn()
            previous = now;
        }
    }
}


总结:


防抖和节流只是减少了事件回调函数的执行次数,并不会减少事件的触发频率。防抖和节流并没有从本质上解决性能问题,我们还应该注意优化我们事件回调函数的逻辑功能,避免在回调中执行比较复杂的DOM操作,减少浏览器reflow和repaint。



参考文章:

https://segmentfault.com/a/1190000018428170

https://blog.csdn.net/xiaomajia029/article/details/82657319
https://www.yht7.com/news/30003

# JavaScript

评论

后参与评论
还没有评论,来说点什么吧~