事件触发控制_前端性能优化:事件的节流throttle与防抖debounce
生活随笔
收集整理的這篇文章主要介紹了
事件触发控制_前端性能优化:事件的节流throttle与防抖debounce
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
scroll 事件是一個非常容易被反復觸發的事件,另外,resize 事件、鼠標事件(比如 mousemove、mouseover 等)、鍵盤事件(keyup、keydown 等)都存在被頻繁觸發的風險。
頻繁觸發回調導致的大量計算會引發頁面的抖動甚至卡頓。為了規避這種情況,我們需要一些手段來控制事件被觸發的頻率。就是在這樣的背景下,throttle(事件節流)和 debounce(事件防抖)出現了。
(閉包形式實現,即返回的是一個函數)
throttle:
// fn是我們需要包裝的事件回調, interval是時間間隔的閾值function throttle(fn, interval) { // last為上一次觸發回調的時間 let last = 0 // 將throttle處理結果當作函數返回 return function () { // 保留調用時的this上下文 let context = this // 保留調用時傳入的參數 let args = arguments // 記錄本次觸發回調的時間 let now = +new Date() // 判斷上次觸發的時間和本次觸發的時間差是否小于時間間隔的閾值 if (now - last >= interval) { // 如果時間間隔大于我們設定的時間間隔閾值,則執行回調 last = now; fn.apply(context, args); } }}// 用throttle來包裝scroll的回調const better_scroll = throttle(() => console.log('觸發了滾動事件'), 1000)document.addEventListener('scroll', better_scroll)Debounce:(有定時器)
// fn是我們需要包裝的事件回調, delay是每次推遲執行的等待時間function debounce(fn, delay) { // 定時器 let timer = null // 將debounce處理結果當作函數返回 return function () { // 保留調用時的this上下文 let context = this // 保留調用時傳入的參數 let args = arguments // 每次事件被觸發時,都去清除之前的舊定時器 if(timer) { clearTimeout(timer) } // 設立新定時器 timer = setTimeout(function () { fn.apply(context, args) }, delay) }}// 用debounce來包裝scroll的回調const better_scroll = debounce(() => console.log('觸發了滾動事件'), 1000)document.addEventListener('scroll', better_scroll)用 Throttle 來優化 Debounce
debounce 的問題在于它“可以一等再等”。試想,如果用戶的操作十分頻繁——他每次都不等 debounce 設置的 delay 時間結束就進行下一次操作,于是每次 debounce 都為該用戶重新生成定時器,回調函數被延遲了不計其數次。頻繁的延遲會導致用戶遲遲得不到響應,用戶同樣會產生“這個頁面卡死了”的觀感。
為了避免弄巧成拙,需要借力 throttle 的思想,打造一個“有底線”的 debounce——等待可以,但必須有原則:delay 時間內,可以為不斷重新生成定時器;但只要delay的時間到了,必須要給用戶一個響應。
// fn是我們需要包裝的事件回調, delay是時間間隔的閾值function throttle(fn, delay) { // last為上一次觸發回調的時間, timer是定時器 let last = 0, timer = null // 將throttle處理結果當作函數返回 return function () { // 保留調用時的this上下文 let context = this // 保留調用時傳入的參數 let args = arguments // 記錄本次觸發回調的時間 let now = +new Date() // 判斷上次觸發的時間和本次觸發的時間差是否小于時間間隔的閾值 if (now - last < delay) { // 如果時間間隔小于我們設定的時間間隔閾值,則為本次觸發操作設立一個新的定時器 clearTimeout(timer) timer = setTimeout(function () { last = now fn.apply(context, args) }, delay) } else { // 如果時間間隔超出了我們設定的時間間隔閾值,那就不等了,無論如何要反饋給用戶一次響應 last = now fn.apply(context, args) } }}// 用新的throttle包裝scroll的回調const better_scroll = throttle(() => console.log('觸發了滾動事件'), 1000)document.addEventListener('scroll', better_scroll)總結
以上是生活随笔為你收集整理的事件触发控制_前端性能优化:事件的节流throttle与防抖debounce的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: html 怎么让tr的css覆盖td的_
- 下一篇: python笔记视频_终于拿到!清华大佬