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