函数防抖与函数节流

前言

有一些浏览器事件能够在很短的事件内快速触发屡次,例如 调整窗口大小向下滚动 页面。例如,若是将事件监听器绑定到窗口滚动事件上,而且用户继续很是快速地向下滚动页面,你的事件可能会在3秒的范围内被触发数千次。这可能会致使一些严重的性能问题,面试

若是在面试中讨论构建应用程序和事件,如滚动、窗口调整大小,或键盘按下的事件时,必定要说起函数防抖动和函数节流来提高页面速度和性能。浏览器

直接绑定函数到scroll事件是很是错误的决定,当用户滚动页面时,页面可能会变得很是慢甚至未响应。而函数防抖和函数节流是解决这个问题的一种方式,经过限制须要通过的事件,直至再次调用函数,在处理一些高频率触发的 DOM 事件的时候,它们都能极大提升用户体验。闭包

函数防抖

若是一个事件被频繁触发屡次,而且触发的时间间隔太短,则防抖函数可使得对应的事件处理函数只执行一次app

// debounce函数用来包裹咱们的事件处理方法
function debounce(fn, delay){
    // 持久化一个定时器
    let timer = null
    
    // 闭包函数能够访问timer
    return function(){
        // 经过 this 和 arguments 得到函数的做用域和参数
        let context = this
        let args = arguments
        // 若是事件被触发,清除timer并从新开始计时
        clearTimeout(timer)
        timer = setTimeout(function() {
            fn.apply(context, args)
        }, delay)
    }
}

function foo(){
    console.log('You are scrolling!')
}

document.addEventListener('scroll', debounce(foo, 50));

函数节流

throttle 的概念理解稍微容易一些,若是一个事件被频繁触发屡次,节流函数能够按照固定频率去执行对应的事件处理方法函数

function throttle(fn, threshold){
    var last
    
    var timer
    
    threshold || (threshold = 250)
    
    return function(){
        let context = this
        let args = arguments
        
        var now = +new Date()
        
        if(last&&now<last+threshold){
            clearTimeout(timer)
            
            timer = setTimeout(function(){
                last = now
                fn.apply(context, args)
            },threshold)
        }else {
            last = now
            fn.apply(context, args)
        }
    }
}
相关文章
相关标签/搜索