函數防抖與函數節流

前言

有一些瀏覽器事件能夠在很短的事件內快速觸發屢次,例如 調整窗口大小向下滾動 頁面。例如,若是將事件監聽器綁定到窗口滾動事件上,而且用戶繼續很是快速地向下滾動頁面,你的事件可能會在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)
        }
    }
}
相關文章
相關標籤/搜索