我所知道的防抖与节流

207 阅读1分钟

场景

最早认识是在一个项目中需要监听页面,即浏览器的滚动;

   //监听页面滚动并执行
    function myScroll () {
        let scrollTop = document.body.scrollTop || 
        document.documentElement.scrollTop;
        console.log('滚动距离:' + scrollTop);
    }
    window.onscroll  = myScroll;

scroll-1.png

嘿嘿~,需求轻松搞定,当很快就发现了问题,轻轻滚动函数居然执行数十次,这频率超乎想象......, 没办法,只好找方法解决这问题;

问题的解决

询问度娘,就找到防抖与节流;

防抖(debounce):指触发事件后在 n 秒内函数只能执行一次,如果在 n 秒内又触发了事件,则会重新计算函数执行时间;

    //防抖
    function debounce(func, wait=300) {
        let timerId;
        //使用闭包方法
        return function (...args) {
            timerId && clearTimeout(timerId);
            timerId = setTimeout(() => {
                //绑定this指向,滚动才执行函数
                func.apply(this, args);
            }, wait);
        };
    };
    //监听页面滚动并执行
    function myScroll () {
        let scrollTop = document.body.scrollTop || 
        document.documentElement.scrollTop;
        console.log('滚动距离:' + scrollTop);
    }
    window.onscroll  = debounce(myScroll);

scroll-2.png

这次可以看到滚轮无限滚动只会执行一次函数,满足需求;

节流(throttle):指连续触发事件但是在 n 秒中只执行一次函数;

    //节流
    function throttle(func, wait=300) {
        let timerId;
        return function (...args) {
            if (!timerId) {
                timerId = setTimeout(() => {
                    timerId = null;
                    func.apply(this, args);
                }, wait);
            }
        }
    }
    //监听页面滚动并执行
    function myScroll () {
        let scrollTop = document.body.scrollTop || 
        document.documentElement.scrollTop;
        console.log('滚动距离:' + scrollTop);
    }
    window.onscroll  = throttle(myScroll);

同种效果,滚动行为每300ms触发一次,节流方法也减少了函数的触发次数,这里图就省略了......;

总结

严格来说,防抖与节流是前端性能优化的方式,可用在监听页面的滚动、浏览器调整窗口大小、输入框的搜索功能,具体怎么用因人而异,看项目需求,具体问题具体分析。