前端性能優(yōu)化---防抖與節(jié)流--02
防抖(Debounce)和節(jié)流(Throttle)是兩種常用的優(yōu)化技術,主要用于控制高頻率的事件觸發(fā),如滾動、輸入、窗口調整大小等。本文將深入探討防抖與節(jié)流的原理、實現(xiàn)方法及其應用場景。
簡單場景就是:輸入框防抖,滾動節(jié)流
1. 防抖(Debounce)
防抖是一種在事件頻繁觸發(fā)時,通過延遲執(zhí)行來減少事件觸發(fā)次數(shù)的技術。防抖的核心思想是:當事件被觸發(fā)時,不立即執(zhí)行處理函數(shù),而是設置一個定時器,如果在定時器未結束前再次觸發(fā)事件,則重新開始計時。這樣可以確保在一定時間內只執(zhí)行一次事件處理函數(shù)。
實現(xiàn)原理:
function debounce(func, wait) { let timeout; return function(...args) { const context = this; clearTimeout(timeout); timeout = setTimeout(() => func.apply(context, args), wait); }; }
示例應用:
在搜索框輸入時,實時發(fā)送請求獲取搜索建議。如果不進行防抖處理,每次輸入都會發(fā)送請求,造成服務器壓力和資源浪費。通過防抖可以優(yōu)化這種場景:
const searchInput = document.getElementById('search'); const handleSearch = debounce((event) => { console.log('Fetching search results for:', event.target.value); // 發(fā)送搜索請求 }, 300); searchInput.addEventListener('input', handleSearch);
2. 節(jié)流(Throttle)
節(jié)流是一種在事件頻繁觸發(fā)時,通過限制函數(shù)執(zhí)行頻率來減少事件處理次數(shù)的技術。節(jié)流的核心思想是:在規(guī)定的時間間隔內只執(zhí)行一次事件處理函數(shù),不論期間事件觸發(fā)了多少次。
實現(xiàn)原理:
function throttle(func, limit) { let inThrottle; return function(...args) { const context = this; if (!inThrottle) { func.apply(context, args); inThrottle = true; setTimeout(() => inThrottle = false, limit); } }; }
示例應用:
在頁面滾動時,實時計算滾動位置以顯示回到頂部按鈕。如果不進行節(jié)流處理,滾動事件會頻繁觸發(fā),導致性能問題。通過節(jié)流可以優(yōu)化這種場景:
const handleScroll = throttle(() => { console.log('Scroll position:', window.scrollY); // 處理滾動事件 }, 200); window.addEventListener('scroll', handleScroll);
3. 防抖與節(jié)流的選擇
防抖和節(jié)流雖然都是用于控制高頻事件,但它們的應用場景有所不同:
- 防抖:適用于頻繁觸發(fā)但只需最后一次結果的場景,如搜索輸入、窗口大小調整等。
- 節(jié)流:適用于持續(xù)觸發(fā)但需要定期執(zhí)行的場景,如滾動事件、窗口滾動位置計算等。
4. 深入優(yōu)化
立即執(zhí)行版防抖:
有時我們希望在事件觸發(fā)時立即執(zhí)行一次,然后再進行防抖控制,可以在防抖函數(shù)中添加一個立即執(zhí)行選項:
function debounce(func, wait, immediate) { let timeout; return function(...args) { const context = this; const callNow = immediate && !timeout; clearTimeout(timeout); timeout = setTimeout(() => { timeout = null; if (!immediate) func.apply(context, args); }, wait); if (callNow) func.apply(context, args); }; }
帶有標識的節(jié)流:
有時我們希望在節(jié)流過程中能夠獲取到當前的狀態(tài),可以在節(jié)流函數(shù)中添加一個標識:
function throttle(func, limit) { let inThrottle; return function(...args) { const context = this; if (!inThrottle) { func.apply(context, args); inThrottle = true; setTimeout(() => inThrottle = false, limit); } }; }
5. 綜合應用
在實際開發(fā)中,防抖與節(jié)流可以結合使用。例如在一個實時搜索的頁面中,用戶輸入時進行防抖處理,而在結果展示時進行節(jié)流處理,以優(yōu)化整體性能。
const searchInput = document.getElementById('search'); const resultsContainer = document.getElementById('results'); const fetchResults = debounce((query) => { console.log('Fetching results for:', query); // 模擬搜索請求 setTimeout(() => { resultsContainer.innerHTML = `Results for: ${query}`; }, 500); }, 300); const handleScroll = throttle(() => { console.log('Scroll position:', window.scrollY); // 處理滾動事件 }, 200); searchInput.addEventListener('input', (event) => { fetchResults(event.target.value); }); window.addEventListener('scroll', handleScroll);
防抖與節(jié)流是前端性能優(yōu)化中的兩項重要技術,通過合理地應用這兩種技術,可以顯著減少高頻事件帶來的性能問題,提升用戶體驗。其他性能優(yōu)化技術,如代碼分割、異步加載、懶加載等,后續(xù)介紹。

浙公網安備 33010602011771號