防抖函數和節流函數是工作中兩種常用的前端性能優化函數,今天我就來總結一下什麼是防抖和節流,並詳細說明一下如何在工作中應用防抖函數和節流函數 ...
防抖和節流函數是工作中兩種常用的前端性能優化函數,今天我就來總結一下什麼是防抖和節流,並詳細說明一下如何在工作中應用防抖和節流函數
什麼是防抖和節流?
在 JavaScript 中,防抖(debounce)和節流(throttle)是用來限制函數執行頻率的兩種常見技術。
防抖(debounce) 是指在某個時間段內,只執行最後一次觸發的函數調用。如果在這個時間段內再次觸發該函數,會重新計時,直到等待時間結束才會執行函數。
這個技術通常用於處理頻繁觸發的事件,比如視窗大小調整、搜索框輸入等。防抖可以避免函數執行過多次,以減少網路開銷和性能負擔。
節流(throttle) 是指在一段時間內限制函數的執行頻率,保證一定時間內只執行一次函數調用。無論觸發頻率多高,都會在指定時間間隔內執行一次函數。
這個技術通常用於處理連續觸發的事件,比如滾動事件、滑鼠移動事件等。節流可以控制函數的執行頻率,以減少資源消耗和提高性能。
手寫一個防抖的工具函數
function debounce(func, delay) {
let timeoutId;
return function() {
const context = this;
const args = arguments;
clearTimeout(timeoutId);
timeoutId = setTimeout(function() {
func.apply(context, args);
}, delay);
};
}
函數說明
- 這個防抖函數接受兩個參數:
func
表示需要進行防抖的函數,delay
表示延遲的時間間隔(以毫秒為單位) - 函數內部使用了一個
timeoutId
變數來保存定時器的標識。當調用防抖函數返回的新函數時,會清除之前的定時器,並設置一個新的定時器。只有在延遲時間內沒有再次調用該新函數時,才會觸發最終的函數執行
使用示例
該示例表示在全局滾動事件中使用防抖函數,每200毫秒內如果觸發滾動事件,那麼不會執行handleScroll()
函數。
然後重新計時200毫秒,再次判斷,直到最後一個200毫秒內沒有觸發滾動事件,才會執行handleScroll()
函數
function handleScroll() {
console.log('Scrolled');
}
const debouncedScroll = debounce(handleScroll, 200);
window.addEventListener('scroll', debouncedScroll);
手寫一個節流的工具函數
function throttle(func, delay) {
let timeoutId;
let lastExecTime = 0;
return function(...args) {
const currentTime = Date.now();
const remainingTime = delay - (currentTime - lastExecTime);
clearTimeout(timeoutId);
if (remainingTime <= 0) {
func.apply(this, args);
lastExecTime = currentTime;
} else {
timeoutId = setTimeout(() => {
func.apply(this, args);
lastExecTime = Date.now();
}, remainingTime);
}
};
}
函數說明
- 這個節流函數接受兩個參數:
func
是要執行的函數,delay
是延遲時間(以毫秒為單位) - 它返回一個新的函數,該函數在調用時會根據指定的延遲時間來限制原始函數的執行頻率
使用示例
在全局滾動事件中使用節流函數,無論在滾動事件的監聽過程中,觸發了幾次handleScroll()
函數,都只會在每200毫秒內執行一次handleScroll()
函數。
function handleScroll() {
console.log('Scrolled');
}
const throttledScroll = throttle(handleScroll, 200);
window.addEventListener('scroll', throttledScroll);
如何在工作中應用防抖和節流
防抖和節流主要應用於:搜索框輸入事件監聽、視窗大小調整事件監聽、按鈕點擊事件監聽、滾動事件監聽、滑鼠移動事件監聽等等場景。
工作中哪些場景可以使用防抖函數?
- 用戶輸入: 當用戶在表單輸入框中頻繁輸入時,可以使用防抖函數來延遲處理用戶輸入,避免頻繁的請求或操作,提高性能和用戶體驗。
- 搜索框: 在搜索框中,當用戶連續輸入關鍵字時,可以使用防抖函數來延遲發送搜索請求,以避免請求過多。
- 視窗調整: 當視窗大小調整時,會觸發resize事件,可以使用防抖函數來限制resize事件的觸發次數,避免頻繁執行調整相關的代碼。
- 按鈕頻繁點擊: 當按鈕被頻繁點擊時,可以使用防抖函數來限制按鈕點擊的觸發次數。
工作中哪些場景可以使用節流函數?
- 用戶輸入: 當用戶在文本框中輸入時,觸發搜索功能。使用節流函數可以限制搜索請求的頻率,以避免頻繁的網路請求。例如,可以設置一個定時器,在用戶輸入後的一小段時間內不觸發搜索請求,只在定時器結束後才進行搜索。
- 無限載入: 當用戶滾動頁面時,觸發載入更多數據的操作。使用節流函數可以限制載入操作的頻率,以提高頁面的響應性能。例如,可以設置一個定時器,在用戶滾動過程中只觸發載入操作的最後一次滾動事件。
- 按鈕頻繁點擊: 當用戶頻繁點擊某個按鈕時,觸發某個操作。使用節流函數可以限制點擊操作的頻率,以避免重覆操作或者混亂的界面狀態。例如,可以設置一個定時器,在用戶點擊後的一小段時間內不觸發重覆操作。
如何使用loadsh.js
工具庫中的防抖和節流函數
實際開發過程中,我們的項目中可能會直接使用loadsh.js
工具庫,來避免重覆造輪子,所以這裡也特地說明一下如何使用loadsh.js
工具庫中的防抖和節流函數
- 安裝
loadsh.js
工具庫
npm install lodash
- 在項目中引入
loadsh.js
工具庫,不同前端項目引入方式不同,請自行鑒別
import { debounce, throttle } from 'loadsh';
- 使用防抖函數,該示例中,
submitData()
函數被限製為每1秒只會執行最後一次,如果在等待時間內多次調用該函數,則會重置1秒的等待時間
// 定義要延遲執行的函數
function submitData(data) {
console.log('保存數據:', data);
}
// 使用debounce函數創建一個延遲執行的函數
const debouncedFn = _.debounce(submitData, 1000);
// 模擬連續觸發保存數據的操作
// 等待1秒後,只會執行最後一次保存數據的操作
debouncedFn('數據1'); // 不會輸出
debouncedFn('數據2'); // 不會輸出
debouncedFn('數據3'); // 輸出 —— 保存數據:數據3
- 使用節流函數,該示例中,
throttledFn()
函數被限製為每秒只能執行一次,如果在等待時間內多次調用該函數,則不會執行
// 定義要減少調用次數的函數
function fetchData(data) {
console.log('拉取數據:', data);
}
// 使用throttle函數創建一個定時執行的函數
const throttledFn = _.throttle(fetchData, 2000);
// 調用throttledFn函數
throttledFn('數據1'); // 輸出 —— 拉取數據: 數據1
// 在1秒內多次調用throttledFn函數
throttledFn('數據2'); // 不會輸出
// 2秒後再次調用throttledFn函數
setTimeout(() => {
throttledFn('數據3'); // 輸出 —— 拉取數據: 數據3
}, 1000);
我是 fx67ll.com,如果您發現本文有什麼錯誤,歡迎在評論區討論指正,感謝您的閱讀!
如果您喜歡這篇文章,歡迎訪問我的 本文github倉庫地址,為我點一顆Star,Thanks~