1. Debouncing (๋๋ฐ์ด์ฑ)
- ๋ง์ง๋ง ์ด๋ฒคํธ๊ฐ ์คํ๋๊ณ ๋์ ์ผ์ ํ ์๊ฐ์ด ์ง๋๋ ๋์ด์ ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ์ง ์์ ๋ ๋ง์ง๋ง์ผ๋ก ์คํ๋ ํจ์๋ง์ ์คํํจ.
- ์ฆ ์ฐ์์ ์ผ๋ก ๋ฐ์ํ ์ด๋ฒคํธ๋ฅผ ํ๋๋ก ์ฒ๋ฆฌ.
- ์๋ ์์ฑ ๊ธฐ๋ฅ์ด๋ ํค์๋ ๊ฒ์ ์ api ํธ์ถ ํ์๋ฅผ ์ต์ํ์ผ๋ก ํ ๋ ์ฃผ๋ก ์ฌ์ฉ.
<body>
<input type="text" />
<div>
<span>default : </span>
<span id="default"></span>
</div>
<div>
<span>debounce : </span>
<span id="debounce"></span>
</div>
</body>
document.querySelector('input').addEventListener('input',(e) => {
const { value } = e.target;
document.getElementById('default').innerText = value;
debounce(value);
})
const debounceFunc = (cb,delay) => {
let timeout;
return (...arg) => {
clearTimeout(timeout);
timeout = setTimeout(() => cb(...arg),delay)
}
}
const debounce = debounceFunc((value) => {
document.getElementById('debounce').innerText = value;
},1000);
์์ ์์๋ฅผ ๋ณด๋ฉด input์ ํ์ดํ์ ํ ๋๋ง๋ค ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ๊ฒ ๋๋ค.
default ํ๊ทธ์ innerText๋ ์ค์๊ฐ ํ์ดํ์ ๊ทธ๋๋ก ๋๋๋ง ํ๋ค.
๋ฐ๋ฉด debounce innerText๋ 1์ด๊ฐ ์ง๋ ํ์์ผ ํ์ดํ ๋ด์ฉ์ ๋๋๋ง ํ๋ค.
์ด๋ ๊ฒ ์ด๋ฒคํธ๊ฐ ์ฐ์์ผ๋ก ๋ฐ์ํ ๋ ์ผ์ ์๊ฐ(1์ด)์ด ์ง๋๊ณ ๋์ ์ถ๊ฐ์ ์ธ ์ด๋ฒคํธ๊ฐ ์๋ค๋ฉด
ํ ๋ฒ์ ์ด๋ฒคํธ๋ฅผ ์คํํ๋ ๊ฒ์ ๋๋ฐ์ด์ค๋ผ๊ณ ํ๋ค.
input์ ํ์ดํ์ ํ ๋๋ง๋ค debounce(value)๊ฐ ํธ์ถ๋๋๋ฐ, ์ด๋ ์ฆ debounceFunc๋ฅผ ํธ์ถํ๋ ๊ฒ์ด๋ค.
debouncFunc๋ ์ผ์ ์๊ฐ์ด ์ง๋ ํ์ ์ฝ๋ฐฑ ํจ์๋ฅผ ๋ฐํํ๋๋ฐ
๋ง์ฝ ์ผ์ ์๊ฐ์ด ์ง๋๊ธฐ ์ ์ ๋๋ค์ ํจ์๋ฅผ ํธ์ถํ๋ค๋ฉด
๊ธฐ์กด์ timeout์ ํ ๋น๋์๋ setTimeout ํจ์๊ฐ clearTimeout์ ์ํด ์ฌ๋ผ์ ธ๋ฒ๋ฆฐ๋ค.
๊ทธ๋ฆฌ๊ณ ๋ ์๋ก์ด ํ์ด๋จธ๊ฐ ๋ง์ถฐ์ง๋ค.
์ฌ๊ธฐ์ debounceFunc๊ฐ ํธ์ถ๋ ๋, timeout์ด ์ด๊ธฐํ๋์ง ์๋?
๊ทธ๋ผ clearํ ๊ฒ๋ ์์ง ์๋?
์๋ ๊ทธ๋ฌ๋ฉด 1000์ด๋ง๋ค ๋ชจ๋ ํธ์ถ์ ๋ค ์คํํ๊ฒ ๋ค?!! ๊ทธ๊ฑด debounce๊ฐ ์๋๋ฐ.. ?
์ด๋ฐ ๋ช์ ๋น ์ ธ๋ฒ๋ ธ๋ค.
์ฝ๋๋ฅผ ์ฒ์ฒํ ๋ถ์ํ๋ฉฐ ๊ตฌ๊ธ๋ง์ ํตํด ๊ฒฐ๋ก ์ ์ป์๋ค.
setTimeout์ด ๋น๋๊ธฐ ํจ์์ด๊ธฐ ๋๋ฌธ์ ํด๋ก์ ๋ก ์ธํด ๊ธฐ์กด์ setTimeout์ timeout์ ๊ณ์ ์ฐธ์กฐํ๊ณ ์๊ณ
์๋ก debounceFunc๊ฐ ํธ์ถ๋ ๋ timeout์ด ์ด๊ธฐํ๋๋ ๊ฒ์ด ์๋ ๊ธฐ์กด์ setTimeout ํจ์๋ฅผ ๋ด๊ณ ์๋ ์ํ์ธ ๊ฒ์ด๋ค.
๋ฐ๋ผ์ clearTimeout์ผ๋ก ๊ธฐ์กด์ setTimeout ํจ์๊ฐ ์ฌ๋ผ์ง๊ณ ,
์๋ก setTimeout์ด timeout์ ํ ๋น๋๋ค.
์ด๋ฌํ ๊ณผ์ ์ผ๋ก debounce๊ฐ ์คํ๋๋ค.
2. Throttling (์ฐ๋กํ๋ง)
- ์ผ์ ์ฃผ๊ธฐ๋ง๋ค ์ด๋ฒคํธ๋ฅผ ๋ฐ์์ํด
- ์ฆ ์ผ์ ์๊ฐ ๋์ ๋ฑ ํ ๋ฒ๋ง ์ด๋ฒคํธ๋ฅผ ๋ฐ์์ํด
- ์ผ์ ์ฃผ๊ธฐ๊ฐ ์ง๋์ง ์์๋๋ฐ ํธ์ถ๋ ํจ์๋ ๋ฌด์ํจ
- ์ฃผ๋ก ์คํฌ๋กค์ ์์น๋ฅผ ํ์ฉํด์ ๋ฌด์ธ๊ฐ ๊ฐ๋ฐ์ ํ ๋ ๋ง์ด ์ฌ์ฉ
<body>
<input type="text" />
<div>
<span>default : </span>
<span id="default"></span>
</div>
<div>
<span>throttle : </span>
<span id="throttle"></span>
</div>
</body>
document.querySelector('input').addEventListener('input',(e) => {
const { value } = e.target;
document.getElementById('default').innerText = value;
throttle(value);
})
let isThrottling;
const throttleFunc = (cb,delay) => {
return (...arg) => {
if(isThrottling) return;
isThrottling = true;
setTimeout(() => {
cb(...arg);
isThrottling = false;
},delay)
}
}
const throttle = throttleFunc((value) => {
document.getElementById('throttle').innerText = value;
},1000);
1. input์ ํ์ดํ์ ํ ๋๋ง๋ค throttle(value);๊ฐ ํธ์ถ๋๋ค.
2. throttle์๋ trottleFunc์ ๋ฐํ ํจ์๊ฐ ํ ๋น๋์ด ์๋ค.
3. ์ต์ด์ isThrottling์ undefined์ด๊ธฐ ๋๋ฌธ์ return๋์ง ์๊ณ ๊ทธ๋๋ก ์คํ๋๋ค.
4.isThrottling์ด true๋ก ์ฌํ ๋น๋๋ค.
5.setTimeoutํจ์๊ฐ ์คํ๋๋ค.
6.์ฌ๊ธฐ์๋ 1์ด์ delay๋ฅผ ์ฃผ์๋๋ฐ, ๋ง์ฝ 1์ด ์์ ๋๋ค์ ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ๋ค๋ฉด
7.throttle(value)๊ฐ ๋ค์ ์คํ๋๋ค.
8.์ด๋ ๋น๋๊ธฐ ํจ์์ธ setTimeout์ด isThrottling์ ๊ฐ์ ํด๋ก์ ์ ์ํด ์์ง ์ฐธ์กฐํ๊ณ ์๋ค.
9.๋ฐ๋ผ์ ์ฝ๋ ์ฒซ๋ฒ์งธ if๋ฌธ์์ isThrottling์ ์๊น true๋ก ์ฌํ ๋น๋์๊ธฐ ๋๋ฌธ์ ํ์ฌ true๋ผ์ ์ฝ๋๊ฐ ๋์ด์ ์คํ๋์ง ์๊ณ return๋๋ค.
10.๋ง์ฝ 1์ด๊ฐ ์ง๋๋ฉด, setTimeout์ ์ฝ๋ฐฑํจ์๊ฐ ์คํ๋๊ณ , ์ธ์๋ก ๋ฐ์ ์ฝ๋ฐฑ ํจ์์ ๋งค๊ฐ๋ณ์(value)๋ฅผ ์ ๋ฌํ๊ฒ ๋๋ค.
11.๊ทธ๋ฆฌ๊ณ ๋์ isThrottling์ false๋ฅผ ์ฌํ ๋นํ๋ค.
12.์ ์ญ ๋ณ์ let isThrottling์ด false๋ก ๊ฐ์ด ๋ฐ๋๊ณ ,
13.๋ค์ ์ด๋ฒคํธ๊ฐ ์คํ๋๋ค๋ฉด ์์ ๊ฐ์ ๊ณผ์ (4๋ฒ ์ดํ)์ ๋ฐ๋ณตํ๊ฒ ๋๋ค.