JS防抖和節流介紹

JS防抖和節流

一.背景

我們日常開發中會經常遇到的問題,用戶的行爲會頻繁的觸發事件執行,對DOM操作、資源加載等耗費性能的處理,很可能導致界面卡頓,甚至瀏覽器的崩潰。函數防抖(debounce)和函數節流(throttle)就是爲了解決類似的需求應運而生的。

二.概念

函數防抖和函數節流都是防止某一時間頻繁觸發,但是這兩兄弟之間原理卻不一樣

函數防抖是某一段時間內只執行一次,而函數節流是間隔時間執行

函數防抖(debounce)與函數節流(throttle)都是爲了限制函數的執行頻次,以優化函數觸發頻率過高導致的響應速度跟不上觸發頻率,出現延遲,假死或卡頓的現象

1.防抖debounce

函數防抖,就是指觸發事件後在規定時間內函數只能執行一次,如果在規定時間內又觸發了事件,則會重新計算函數的執行時間

​ 通俗的說,當我們一個動作,連續被觸發,那麼就只執行最後一次,比如我們電梯進人,電梯需要感應到沒有人了纔會自動觀門,每次進入一個,電梯就會多等幾秒鐘纔會關閉

 		var ipt1 = document.querySelector('.ipt1');
        var comment = document.querySelector('.comment');

        //沒有防抖
        ipt1.onkeyup = function () {
            $.ajax({
                method: 'get',
                url: '',
                data: {
                    searchText: ipt1.value
                },
                success: function (res) {
                    comment.innerHTML += res;
                }
            });
        }

這是沒有防抖的代碼,文本框每次輸入,鍵盤按下的時候,都會執行,大大的浪費了請求的資源,所以呢,我們優化一下上述代碼,使用防抖原理

 		// 防抖
        var deferTimer;
        ipt2.onkeyup = function () {
            clearTimeout(deferTimer);
            deferTimer = setTimeout(function () {
                $.ajax({
                    method: 'get',
                    url: '',
                    data: {
                        searchText: ipt2.value
                    },
                    success: function (res) {
                        comment.innerHTML += res;
                    }
                });
            }, 400);
        }

這樣我們就能節省請求的資源了,現在對防抖封裝一下,以便日後使用:

  		/*
        *   防抖函數
        *   @delay  延遲多少毫秒
        *   @callback 請求網絡資源的回調函數
        */
        function debounce(delay, callback) {
            var deferTimer;
            return function () {
                //清除延時器
                clearTimeout(deferTimer);
                deferTimer = setTimeout(function () {
                    callback();
                }, delay);
            }
        }

2.節流throttle

規定在一個單位時間內,只能觸發一次函數。如果這個單位時間內觸發多次函數,只有一次生效。

跟我們生活的一個情景很相似,進入公司裏面時,刷卡過閘機時,每個人等待幾秒後關閉,等待下一個人

  		//節流
        var lastTime = Date.now();
        ipt3.onkeyup = function () {
            var nowTime = Date.now();
            if (nowTime - lastTime >= 1000) {
                lastTime = nowTime;
                $.ajax({
                    method: 'get',
                    url: '',
                    data: {
                        searchText: ipt2.value
                    },
                    success: function (res) {
                        comment.innerHTML += res;
                    }
                });
            }
        }

上述代碼就是採用了函數節流的原理實現,同樣,下面封裝一個節流函數

  		/*
        *   節流函數
        *   @delay  延遲多少毫秒
        *   @callback 請求網絡資源的回調函數
        */
        function throttle(delay, callback) {
            var lastTime = Date.now();
            return function () {
                var nowTime = Date.now();
                //對比時間搓,如果超過了規定時間則可以執行
                if (nowTime - lastTime >= delay) {
                    lastTime = nowTime;
                    callback();
                }
            }
        }

三.應用場景

1.防抖 debounce應用

  • search搜索聯想,用戶在不斷輸入值時,用防抖來節約請求資源。

  • window觸發resize的時候,不斷的調整瀏覽器窗口大小會不斷的觸發這個事件,用防抖來讓其只觸發一次。

  • 驗證手機號是否註冊時

2.節流throttle應用

  • 鼠標不斷點擊觸發,mousedown單位時間內只觸發一次 (典型的應用:拖拽)
  • 監聽滾動事件,比如是否滑到底部自動加載更多,用throttle來判斷
  • 高頻點擊提交,表單重複提交

四.總結

函數節流不管事件觸發有多頻繁,都會保證在規定時間內一定會執行一次真正的事件處理函數,而函數防抖只是在最後一次事件後才觸發一次函數。

函數防抖就是法師發技能的時候要讀條,技能讀條沒完再按技能就會重新讀條。

函數節流就是射手射擊的射速,就算不停按着鼠標射擊,也只會在規定射速內射出子彈。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章