去抖 Debounce & 節流 Throttle 優化前端效能
在現代前端開發中,Debounce 和 Throttle 是兩個常見的技術,用於控制高頻率事件的觸發次數。這些技術能夠幫助優化效能,提升應用的響應速度和用戶體驗。本篇文章將介紹 Debounce 和 Throttle 的概念、區別以及如何在 Vue 3 中使用這些技術。
去抖 Debounce
Debounce 的概念是將高頻率觸發的事件(如輸入框輸入事件)進行延遲處理,只有在事件停止觸發一段時間後才執行相應的函數。這樣可以防止多次重複執行相同的操作
原理
兩秒後在執行,兩秒內有人又來,就再延後
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function debounce(func, delay) {
let timer = null;
return function(...args) {
clearTimeout(timer);
timer = setTimeout(() => {
func(...args); // 等過 delay 才真正執行
}, delay);
}
}
const debouncedFunction = debounce(function(e) {
console.log(e.target.value);
}, 2000);
document.querySelector('input').addEventListener('input', debouncedFunction);
使用場景
- 按鈕提交:防止多次提交按鈕,只執行最後一次提交
- 伺服器驗證:表單驗證需要伺服器端配合時,只執行連續輸入事件的最後一次,例如即時搜尋、Email 是否被註冊過
範例
不需要重複造輪,可以直接使用 lodash-es,是使用 lodash-es
不是 lodash
哦,lodash-es
利用 tree shaking 技術來減少最終打包文件的大小
1
npm install --save lodash-es
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<template>
<div>
<input type="text" v-on:input="handleInput" />
<p>搜尋結果:</p>
</div>
</template>
<script setup>
import { debounce } from 'lodash-es';
import { ref } from 'vue';
const input = ref('');
const searchResult = ref('');
async function fetchSearchResult(query) {
// 模擬 API 請求
return new Promise((resolve) => {
setTimeout(() => {
resolve(`搜尋結果為:${query}`);
}, 500);
});
};
const handleInput = debounce(async (event) => {
input.value = event.target.value;
searchResult.value = await fetchSearchResult(input.value);
}, 2000);
</script>
節流 Throttle
Throttle 的概念是將高頻率觸發的事件進行節流處理,在一定的時間間隔內只執行一次函數。這樣可以確保在特定時間內,事件處理函數最多只會被調用一次
原理
與 Debounce 的程式邏輯相似,只多了一個時間間隔的判斷 (例如:兩秒內只有一次)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function throttle(func, delay) {
let inThrottle = false;
return function(...args) {
if (!inThrottle) { // 正在執行,就跳過
func(...args);
inThrottle = true;
setTimeout(() => {
inThrottle = false; // delay 後才釋放 inThrottle,讓後面的人可以再執行
}, delay);
}
}
}
const throttledFunction = throttle(function(e) {
console.log(e.target.value);
}, 2000);
document.querySelector('input').addEventListener('input', throttledFunction);
使用場景
- 拖曳:固定時間內只執行一次,防止超高頻次觸動位置變動
- 縮放:監控瀏覽器 resize
- 動畫:避免短時間內多次觸發動畫引發效能問題
範例
這裡也是直接使用 lodash-es
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<template>
<div>
<div v-on:scroll="handleScroll" style="height: 200px; overflow-y: scroll;">
<div style="height: 1000px;">Scroll me</div>
</div>
<p>滾動位置:</p>
</div>
</template>
<script setup>
import { throttle } from 'lodash-es';
import { ref } from 'vue';
const scrollPosition = ref(0);
const handleScroll = throttle((event) => {
scrollPosition.value = event.target.scrollTop;
}, 2000);
</script>
總結
Debounce 和 Throttle 是兩個強大的工具,可以幫助控制高頻事件的觸發,從而優化效能。Debounce 適用於需要在事件停止後執行的場景,而 Throttle 適用於需要在固定時間間隔內執行的場景。在實際運用中,我們可以使用 lodash 庫輕鬆實現這些功能,提升應用的用戶體驗和效能。
參考資料
This post is licensed under CC BY 4.0 by the author.