瀏覽器中某些計算和處理要比其餘的昂貴不少。例如DOM操做比DOM交互須要更多的時間和cpu時間,爲了提高性能,減小DOM操做,因而,函數節流防抖和應運而生,其函數節流的基本思想是指,某些代碼不能夠在沒有間斷的狀況下連續重複執行。函數防抖的基本思想是指,一個頻繁觸發的事情只讓最後一次執行。下面就讓咱們來認真瞭解下這常常使用的函數節流和防抖。git
函數節流:一個函數執行一次後,只有大於設定的執行週期後纔會執行第二次。有個須要頻繁觸發函數,出於優化性能角度,在規定時間內,只讓函數觸發的第一次生效,後面不生效。github
下面主要介紹時間戳和定時器兩種方式來實現節流函數。瀏覽器
根據函數節流的原理,咱們也能夠不依賴 setTimeout
實現函數節流。app
function throttle(fn, delay) { // 記錄上一次函數觸發的時間 var lastTime = 0; return function() { // 記錄當前函數觸發的時間 var nowTime = Date.now(); if (nowTime - lastTime > delay) { // 修正this指向問題 fn.call(this); // 同步時間 lastTime = nowTime; } } }
測試代碼:函數
// test function testThrottle(e, content) { console.log(e, content); } var testThrottleFn = throttle(testThrottle, 1000); // 節流函數 document.onmousemove = function (e) { testThrottleFn(e, 'throttle'); // 給節流函數傳參 }
其實現原理,經過比對上一次執行時間與本次執行時間的時間差與間隔時間的大小關係,來判斷是否執行函數。若時間差大於間隔時間,則馬上執行一次函數。並更新上一次執行時間。性能
function throttle(fn, delay) { var timer; return function () { var _this = this; var args = arguments; if (timer) { return; } timer = setTimeout(function () { fn.apply(_this, args); timer = null; // 在delay後執行完fn以後清空timer,此時timer爲假, throttle觸發能夠進入計時器 }, delay) } }
測試代碼:測試
function testThrottle(e, content) { console.log(e, content); } var testThrottleFn = throttle(testThrottle, 2000); // 節流函數 document.onmousemove = function (e) { testThrottleFn(e, 'throttle'); // 給節流函數傳參 }
上面例子中,若是咱們一直在瀏覽器中移動鼠標(好比10s
),則在這10s
內會每隔2s
執行一次testThrottle
,這就是函數節流。優化
函數節流的目的,是爲了限制函數一段時間內只能執行一次。所以,定時器實現節流函數經過使用定時任務,延時方法執行。在延時的時間內,方法若被觸發,則直接退出方法。從而,實現函數一段時間內只執行一次。this
須要間隔必定時間觸發回調來控制函數調用頻率:code
DOM
元素的拖拽功能實現(mousemove)Canvas
模擬畫板功能(mousemove)防抖函數:一個須要頻繁觸發的函數,在規定時間內,只讓最後一次生效,前面的不生效。
function debounce(fn, delay) { var timer = null; return function () { var _this = this; // 取debounce執行做用域的this var args = arguments; if (timer) { clearTimeout(timer); } timer = setTimeout(function () { fn.apply(_this, args); // 用apply指向調用debounce的對象, 至關於_this.fn(args); }, delay); }; }
測試代碼:
function testDebounce(e, content) { console.log(e, content); } var testDebounceFn = debounce(testDebounce, 1000); // 防抖函數 document.onmousemove = function (e) { testDebounceFn(e, 'debounce'); // 給防抖函數傳參 }
上面例子中的debounce
就是防抖函數,在document
中鼠標移動的時候,會在onmousemove
最後觸發的1s
後執行回調函數testDebounce
;若是咱們一直在瀏覽器中移動鼠標(好比10s
),會發現會在10+1s
後纔會執行testDebounce
函數(由於clearTimeout(timer)
),這個就是函數防抖。
對於連續的事件響應咱們只須要執行一次回調:
函數節流和函數去抖的核心其實就是限制某一個方法被頻繁觸發,其目的都是,下降回調執行頻率,節省計算資源,提升瀏覽器的性能。
更多優質文章能夠訪問GitHub博客,歡迎帥哥美女前來Star!!!