【前端帮帮忙】第7期 关于节流(throttle)和防抖(debounce)的理解
節流和防抖在我們平時的項目中挺常用的,也是面試中經常會被提問的知識點,今天我們一起來學習一下。
節流
簡單理解就是:控制函數每隔n秒執行一次。
作用
防止用戶高頻率的觸發事件,剛好這個事件又需要處理大量的計算和渲染而帶來的性能問題。
應用場景
- onscroll
- onresize
- mousemove
- touchmove
- ...
示例
這邊我們以onscroll來寫個例子,加深理解。
比如有這樣一個場景:我們需要判斷瀏覽器滾動條滾動到底部的時候去動態加載一些數據,可能我們直接就會寫上以下的代碼:
let obj = document.querySelector('.throttle-test'); let _count = 0;obj.onscroll = function () {// 假設已經滾動到底部了,我們給_count加1。_count++;console.log('執行次數:' + _count); } 復制代碼我們來看下瀏覽器的打印結果,看以下gif圖:
可以看到,函數執行了20次,很顯然這并不是我們想要的,因為onscroll事件并不會等你滾動到底部了再去觸發事件,而是會不間斷的觸發,這就很容易引發一些性能問題,這時候就需要用到節流了。
我們把代碼做下修改:
let obj = document.querySelector('.throttle-test'); let _count = 0; let _canRun = true; obj.onscroll = function () {if (!_canRun) {return false;}_canRun = false;setTimeout(function () {// 假設已經滾動到底部了,我們給_count加1。_count++;console.log('執行次數:'+_count);_canRun = true;}, 500); } 復制代碼通過以下gif圖,我們可以看到,函數最終只執行了2次。
通過一個定時器,我們控制函數每隔500毫秒再執行一次,大大降低了執行頻率,從而提升性能。
節流概念理解
節流跟防抖,它們既有相似之處但又有所不同,很容易混淆。這里通過比喻來加深理解,先來說說節流。
節流的概念可以想象一下水壩,你建了水壩在河道中,不能讓水流動不了,你只能讓水流慢些。換言之,你不能讓用戶的方法都不執行。(個人比較喜歡這個比喻,因為它很形象的說出了跟防抖的區別。)
防抖
控制函數在n秒內只能執行一次,如果用戶在n秒內重復的觸發事件,則重新計時且函數不會被執行,只有等到用戶不再觸發事件的時候才去執行一次。
作用跟節流類似,也是為了防止用戶高頻率的觸發事件所引發的性能問題。
防抖概念理解
可以想象一下做電梯,當有人進入電梯(觸發事件),那電梯將在10秒后出發(執行事件),這時如果又有人進入電梯了(在10秒內再次觸發了事件),我們又得重新等10秒才能觸發(重新計時)。
示例
有個文本框讓用戶填寫用戶名,當用戶輸入字符時,我們需要實時發請求到后臺去驗證用戶名是否有重復的。實際上,在加入防抖機制前,用戶輸入helloworld后,我們已經發送了10次請求了,很顯然是不可取的。
看代碼:
let obj = document.querySelector('#testInput'); // 獲取文本輸入框 let _count = 0;obj.onkeyup = function () {_count++;console.log('執行次數:' + _count); } 復制代碼我們來給代碼加入防抖機制:
我們只能假設用戶在停頓n秒內沒有再觸發事件,我們就判定用戶已經輸入完成了,這時再發送請求。
看代碼:
let obj = document.querySelector('#testInput'); let timer = null; let _count = 0;obj.onkeyup = function () {clearTimeout(timer); // 清除定時器,重新計時timer = setTimeout(function () {_count++;console.log('執行次數:'+_count);}, 800); } 復制代碼通過動圖,可以看到,當我一直輸入的時候,事件是不會被觸發的,直到我停止輸入才會觸發一次。
實現思路:我們把目標代碼放入到一個定時器里,如果事件被頻繁的觸發,目標代碼將不會被執行。為什么不執行呢,因為我們前面加了clearTimeout。相當于中途不斷的有人進入電梯,電梯又得重新倒計時10秒才會啟動一樣,直到用戶沒再輸入了(沒人再進入電梯了),這時候目標代碼才會按照我們設定的時間再去執行一次(電梯才會啟動)。
節流和防抖的區別
- 節流:目標代碼會按照我們設定的時間間隔即每隔n秒就執行一次
- 防抖:在用戶不觸發事件時,才去執行目標代碼,并且抑制了本來在事件中要執行的動作;當事件被一直觸發的情況下,目標代碼有可能不會被執行
- 函數節流會用在比input,keyup更頻繁觸發的事件中,如resize, touchmove, mousemove, scroll。節流會強制函數以固定的速率執行。因此這個方法比較適合應用于動畫相關的場景。
最后
感謝您的閱讀,希望對你有所幫助。文中如果有描述不當的地方,煩請指正,感激不盡。 另外文中所演示的代碼僅用來測試使用,并不適合用在實際開發中,實際開發可以使用Lodash庫中的節流和防抖方法,這里就不貼代碼了,畢竟考慮的比較全面哈。
Lodash庫的地址:
節流:www.lodashjs.com/docs/4.17.5…
防抖:www.lodashjs.com/docs/4.17.5…
關注
歡迎大家關注我的公眾號前端幫幫忙,一起交流學習,謝謝~
參考: zhuanlan.zhihu.com/p/38313717
總結
以上是生活随笔為你收集整理的【前端帮帮忙】第7期 关于节流(throttle)和防抖(debounce)的理解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 数据库相关题
- 下一篇: @RequestMapping中meth