js防抖和節流

web開發中常常會作滾動監聽,好比商品分類功能:左右兩列,左側類目,右側商品,須要監聽右測商品列表的滾動,滾到哪一個類目區間,左側就點亮哪一個類目標籤。若是在滾動的過程當中一直監聽而不作性能優化的話,瀏覽器是很容易卡死的。下面提供兩種優化性能的方法:web

一、防抖:在滾動過程當中不執行操做,只在結束滾動一段時間內再也不滾動才執行,這裏的一段時間能夠是500毫秒也能夠是1秒,視具體業務而定。瀏覽器

// js防抖核心代碼

function debounce (fn, delay) {
  let timer = null
  // 閉包
  return () => {
    // 若是當前正處在某個計時過程當中,那麼就清除這次計時開始下一次計時,
    // 不然不清除,直接開始下一次計時,計時滿delay毫秒後纔會觸發fn函數。
    if (timer) {
      clearTimeout(timer)
    }
    // 開始下一次計時
    timer = setTimeout(fn, delay)
  }
}

function handleScroll () {
  console.log('滑動後一秒鐘內再也不滑動我就執行一次', Math.random())
}

window.addEventListener('scroll', debounce(handleScroll, 1000))

查看演示請狠狠地點擊:js防抖demo性能優化

二、節流:若是但願即節省性能又不犧牲用戶體驗,就仍然在滾動中實時監聽,只不過下降監聽的「頻率」,好比1秒才執行一次。下面提供兩種實現方法(時間戳、定時器)。閉包

// js節流核心代碼

// 時間戳
function throttle1 (fn, delay) {
  let prev = Date.now()
  // 閉包
  return () => {
    let now = Date.now()
    if (now - prev >= delay) {
      fn()
      prev = Date.now()
    }
  }
}

// 定時器
function throttle2 (fn, delay) {
  let timer = null
  // 閉包
  return () => {
    if (!timer) {
      timer = setTimeout(() => {
        fn()
        timer = null
      }, delay)
    }
  }
}

function handleScroll () {
  console.log('滑動過程當中我一秒鐘才執行一次', Math.random())
}

window.addEventListener('scroll', throttle1(handleScroll, 1000))
// window.addEventListener('scroll', throttle2(handleScroll, 1000))

查看演示請狠狠地點擊:js節流demodom

相關文章
相關標籤/搜索