ํ‹ฐ์Šคํ† ๋ฆฌ ๋ทฐ

ํ˜ธ์ถœ ์Šค์ผ€์ค„๋ง

ํ•จ์ˆ˜๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ ์ฆ‰์‹œ ํ˜ธ์ถœํ•˜์ง€ ์•Š๊ณ  ์ผ์ • ์‹œ๊ฐ„์ด ๊ฒฝ๊ณผ๋œ ์ดํ›„์— ํ˜ธ์ถœ๋˜๋„๋ก ํ•จ์ˆ˜ ํ˜ธ์ถœ์„ ์˜ˆ์•ฝํ•˜๋ ค๋ฉด ํƒ€์ด๋จธ ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ˜ธ์ถœ ์Šค์ผ€์ค„๋ง์ด๋ผ ํ•ฉ๋‹ˆ๋‹ค.

 

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” ํƒ€์ด๋จธ๋ฅผ ์ƒ์„ฑ/์ œ๊ฑฐํ•  ์ˆ˜ ์žˆ๋Š” ํƒ€์ด๋จธ ํ•จ์ˆ˜๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ECMAScrip ์‚ฌ์–‘์— ์ •์˜๋œ ๋นŒํŠธ์ธ ํ•จ์ˆ˜๊ฐ€ ์•„๋‹ˆ๋ฉฐ ๋ธŒ๋ผ์šฐ์ €/Node.js ํ™˜๊ฒฝ์—์„œ ์ „์—ญ ๊ฐ์ฒด์˜ ๋ฉ”์„œ๋“œ๋กœ์„œ ์ œ๊ณตํ•˜๋Š” ํ˜ธ์ŠคํŠธ ๊ฐ์ฒด์ž…๋‹ˆ๋‹ค. ํƒ€์ด๋จธ๋ฅผ ์ƒ์„ฑํ•˜๋Š” setTimeout๊ณผ setInterval ํƒ€์ด๋จธ ํ•จ์ˆ˜๋Š” ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ ๋ฐฉ์‹์œผ๋กœ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค.


ํƒ€์ด๋จธ ํ•จ์ˆ˜

setTimeout / clearTimout

setTimeout ํ•จ์ˆ˜๋Š” ๋‘๋ฒˆ์งธ ์ธ์ˆ˜๋กœ ์ „๋‹ฌ๋ฐ›์€ ์‹œ๊ฐ„(ms, 1/1000์ดˆ)์œผ๋กœ ๋‹จ ํ•œ ๋ฒˆ ๋™์ž‘ํ•˜๋Š” ํƒ€์ด๋จธ๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์ดํ›„ ํƒ€์ด๋จธ๊ฐ€ ๋งŒ๋ฃŒ๋˜๋ฉด ์ฒซ ๋ฒˆ์งธ ์ธ์ˆ˜๋กœ ์ „๋‹ฌ๋ฐ›์€ ์ฝœ๋ฐฑ ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค. ์ฆ‰, setTimeout ํ•จ์ˆ˜์˜ ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋Š” ๋‘ ๋ฒˆ์งธ ์ธ์ˆ˜๋กœ ์ „๋‹ฌ๋ฐ›์€ ์‹œ๊ฐ„ ์ดํ›„ ๋‹จ ํ•œ ๋ฒˆ ์‹คํ–‰๋˜๋„๋ก ํ˜ธ์ถœ ์Šค์ผ€์ค„๋ง๋ฉ๋‹ˆ๋‹ค.

 

const timeoutId = setTimeout(func|code[, delay, param1, param2, ...]);

 

๋งค๊ฐœ๋ณ€์ˆ˜ ์„ค๋ช…
func ํƒ€์ด๋จธ๊ฐ€ ๋งŒ๋ฃŒ๋œ ๋’ค ํ˜ธ์ถœ๋  ์ฝœ๋ฐฑ ํ•จ์ˆ˜
delay ํƒ€์ด๋จธ ๋งŒ๋ฃŒ ์‹œ๊ฐ„ (์ธ์ˆ˜ ์ „๋‹ฌ์„ ์ƒ๋žตํ•˜๋ฉด ๊ธฐ๋ณธ๊ฐ’ 0์ด ์ง€์ •)
param1,
param2, ...
ํ˜ธ์ถœ ์Šค์ผ€์ค„๋ง๋œ ์ฝœ๋ฐฑ ํ•จ์ˆ˜์— ์ „๋‹ฌํ•ด์•ผ ํ•  ์ธ์ˆ˜๊ฐ€ ์กด์žฌํ•˜๋Š” ๊ฒฝ์šฐ ์„ธ ๋ฒˆ์งธ ์ดํ›„์˜ ์ธ์ˆ˜๋กœ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์Œ
*IE9 ์ดํ•˜์—์„œ๋Š” ์ฝœ๋ฐฑ ํ•จ์ˆ˜์— ์ธ์ˆ˜๋ฅผ ์ „๋‹ฌํ•  ์ˆ˜ ์—†์Œ

 

// 1์ดˆ(1000ms) ํ›„ ํƒ€์ด๋จธ๊ฐ€ ๋งŒ๋ฃŒ๋˜๋ฉด ์ฝœ๋ฐฑ ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋œ๋‹ค.
setTimeout(() => console.log('Hi!'), 1000);

// 1์ดˆ(1000ms) ํ›„ ํƒ€์ด๋จธ๊ฐ€ ๋งŒ๋ฃŒ๋˜๋ฉด ์ฝœ๋ฐฑ ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋œ๋‹ค.
// ์ด๋•Œ ์ฝœ๋ฐฑ ํ•จ์ˆ˜์— 'Lee'๊ฐ€ ์ธ์ˆ˜๋กœ ์ „๋‹ฌ๋œ๋‹ค.
setTimeout(name => console.log(`Hi! ${name}.`), 1000, 'Lee');

// ๋‘ ๋ฒˆ์งธ ์ธ์ˆ˜(delay)๋ฅผ ์ƒ๋žตํ•˜๋ฉด ๊ธฐ๋ณธ๊ฐ’ 0์ด ์ง€์ •๋œ๋‹ค.
setTimeout(() => console.log('Hello!'));

 

setTimeout ํ•จ์ˆ˜๋Š” ์ƒ์„ฑ๋œ ํƒ€์ด๋จธ๋ฅผ ์‹๋ณ„ํ•  ์ˆ˜ ์žˆ๋Š” ๊ณ ์œ ํ•œ ํƒ€์ด๋จธ id๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋ฉฐ ์ด๋ฅผ ํ˜ธ์ถœ ์Šค์ผ€์ค„๋ง์„ ์ทจ์†Œํ•˜๋Š” clearTimeout ํ•จ์ˆ˜์˜ ์ธ์ˆ˜๋กœ ์ „๋‹ฌํ•˜์—ฌ ํƒ€์ด๋จธ๋ฅผ ์ทจ์†Œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

// 1์ดˆ(1000ms) ํ›„ ํƒ€์ด๋จธ๊ฐ€ ๋งŒ๋ฃŒ๋˜๋ฉด ์ฝœ๋ฐฑ ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋œ๋‹ค.
// setTimeout ํ•จ์ˆ˜๋Š” ์ƒ์„ฑ๋œ ํƒ€์ด๋จธ๋ฅผ ์‹๋ณ„ํ•  ์ˆ˜ ์žˆ๋Š” ๊ณ ์œ ํ•œ ํƒ€์ด๋จธ id๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
const timerId = setTimeout(() => console.log('Hi!'), 1000);

// setTimeout ํ•จ์ˆ˜๊ฐ€ ๋ฐ˜ํ™˜ํ•œ ํƒ€์ด๋จธ id๋ฅผ clearTimeout ํ•จ์ˆ˜์˜ ์ธ์ˆ˜๋กœ ์ „๋‹ฌํ•˜์—ฌ ํƒ€์ด๋จธ๋ฅผ
// ์ทจ์†Œํ•œ๋‹ค. ํƒ€์ด๋จธ๊ฐ€ ์ทจ์†Œ๋˜๋ฉด setTimeout ํ•จ์ˆ˜์˜ ์ฝœ๋ฐฑ ํ•จ์ˆ˜๊ฐ€ ์‹คํ–‰๋˜์ง€ ์•Š๋Š”๋‹ค.
clearTimeout(timerId);

 

*id๋Š” ๋ธŒ๋ผ์šฐ์ € ํ™˜๊ฒฝ์ธ ๊ฒฝ์šฐ ์ˆซ์ž, Node.js ํ™˜๊ฒฝ์ธ ๊ฒฝ์šฐ ๊ฐ์ฒด

 

setInterval / clearInterval

setInterval ํ•จ์ˆ˜๋Š” ๋‘๋ฒˆ์งธ ์ธ์ˆ˜๋กœ ์ „๋‹ฌ๋ฐ›์€ ์‹œ๊ฐ„(ms, 1/1000์ดˆ)์œผ๋กœ ๋ฐ˜๋ณต ๋™์ž‘ํ•˜๋Š” ํƒ€์ด๋จธ๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์ดํ›„ ํƒ€์ด๋จธ๊ฐ€ ๋งŒ๋ฃŒ๋  ๋•Œ๋งˆ๋‹ค ์ฒซ ๋ฒˆ์งธ ์ธ์ˆ˜๋กœ ์ „๋‹ฌ๋ฐ›์€ ์ฝœ๋ฐฑ ํ•จ์ˆ˜๊ฐ€ ๋ฐ˜๋ณต ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค. ์ฆ‰, setInterval ํ•จ์ˆ˜์˜ ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋Š” ๋‘ ๋ฒˆ์งธ ์ธ์ˆ˜๋กœ ์ „๋‹ฌ๋ฐ›์€ ์‹œ๊ฐ„์ด ๊ฒฝ๊ณผํ•  ๋•Œ๋งˆ๋‹ค ๋ฐ˜๋ณต ์‹คํ–‰๋˜๋„๋ก ํ˜ธ์ถœ ์Šค์ผ€์ค„๋ง๋ฉ๋‹ˆ๋‹ค.

 

const timeoutId = setInterval(func|code[, delay, param1, param2, ...]);

 

setInterval ํ•จ์ˆ˜์— ์ „๋‹ฌํ•  ์ธ์ˆ˜๋Š” setTimeout๊ณผ ๋™์ผํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ setInterval ํ•จ์ˆ˜๋„ ์ƒ์„ฑ๋œ ํƒ€์ด๋จธ๋ฅผ ์‹๋ณ„ํ•  ์ˆ˜ ์žˆ๋Š” ๊ณ ์œ ํ•œ id๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋ฉฐ ์ด๋ฅผ clearInterval ํ•จ์ˆ˜์˜ ์ธ์ˆ˜๋กœ ์ „๋‹ฌํ•˜์—ฌ ํ˜ธ์ถœ ์Šค์ผ€์ค„๋ง์„ ์ทจ์†Œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

let count = 1;

// 1์ดˆ(1000ms) ํ›„ ํƒ€์ด๋จธ๊ฐ€ ๋งŒ๋ฃŒ๋  ๋•Œ๋งˆ๋‹ค ์ฝœ๋ฐฑ ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋œ๋‹ค.
// setInterval ํ•จ์ˆ˜๋Š” ์ƒ์„ฑ๋œ ํƒ€์ด๋จธ๋ฅผ ์‹๋ณ„ํ•  ์ˆ˜ ์žˆ๋Š” ๊ณ ์œ ํ•œ ํƒ€์ด๋จธ id๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
const timeoutId = setInterval(() => {
  console.log(count); // 1 2 3 4 5
  // count๊ฐ€ 5์ด๋ฉด setInterval ํ•จ์ˆ˜๊ฐ€ ๋ฐ˜ํ™˜ํ•œ ํƒ€์ด๋จธ id๋ฅผ clearInterval ํ•จ์ˆ˜์˜
  // ์ธ์ˆ˜๋กœ ์ „๋‹ฌํ•˜์—ฌ ํƒ€์ด๋จธ๋ฅผ ์ทจ์†Œํ•œ๋‹ค. ํƒ€์ด๋จธ๊ฐ€ ์ทจ์†Œ๋˜๋ฉด setInterval ํ•จ์ˆ˜์˜ ์ฝœ๋ฐฑ ํ•จ์ˆ˜๊ฐ€
  // ์‹คํ–‰๋˜์ง€ ์•Š๋Š”๋‹ค.
  if (count++ === 5) clearInterval(timeoutId);
}, 1000);

๋””๋ฐ”์šด์Šค์™€ ์Šค๋กœํ‹€

scroll, resize, input, mousemove ๊ฐ™์ด ์งง์€ ์‹œ๊ฐ„ ๊ฐ„๊ฒฉ์œผ๋กœ ์—ฐ์†ํ•ด์„œ ๋ฐœ์ƒํ•˜๋Š” ์ด๋ฒคํŠธ์— ๋ฐ”์ธ๋”ฉํ•œ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๋Š” ๊ณผ๋„ํ•˜๊ฒŒ ํ˜ธ์ถœ๋˜์–ด ์„ฑ๋Šฅ์— ๋ฌธ์ œ๋ฅผ ์ผ์œผํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋””๋ฐ”์šด์Šค์™€ ์Šค๋กœํ‹€์€ ์ด๋Ÿฌํ•œ ์ด๋ฒคํŠธ๋ฅผ ๊ทธ๋ฃนํ™”ํ•ด์„œ ๊ณผ๋„ํ•œ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ์˜ ํ˜ธ์ถœ์„ ๋ฐฉ์ง€ํ•˜๋Š” ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๊ธฐ๋ฒ•์ž…๋‹ˆ๋‹ค.

 

์ด๋Ÿฌํ•œ ๋””๋ฐ”์šด์Šค์™€ ์ŠคํŠธ๋กค์˜ ๊ตฌํ˜„์—๋Š” ํƒ€์ด๋จธ ํ•จ์ˆ˜๊ฐ€ ์‚ฌ์šฉ๋˜๋ฉฐ ์ด๋ฒคํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•  ๋•Œ ๋งค์šฐ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค.

 

๋””๋ฐ”์šด์Šค(debounce)

๋””๋ฐ”์šด์Šค๋Š” ์งง์€ ์‹œ๊ฐ„ ๊ฐ„๊ฒฉ์œผ๋กœ ์ด๋ฒคํŠธ๊ฐ€ ์—ฐ์†ํ•ด์„œ ๋ฐœ์ƒํ•˜๋ฉด ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ํ˜ธ์ถœํ•˜์ง€ ์•Š๋‹ค๊ฐ€ ์ผ์ • ์‹œ๊ฐ„์ด ๊ฒฝ๊ณผํ•œ ์ดํ›„์— ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ํ•œ ๋ฒˆ๋งŒ ํ˜ธ์ถœ๋˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค. ์ฆ‰, ๋””๋ฐ”์šด์Šค๋Š” ์ด๋ฒคํŠธ๋ฅผ ๊ทธ๋ฃนํ™”ํ•ด์„œ ๋งˆ์ง€๋ง‰์— ํ•œ ๋ฒˆ๋งŒ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ํ˜ธ์ถœ๋˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.

 

์˜ˆ๋ฅผ ๋“ค์–ด ํ…์ŠคํŠธ ์ž…๋ ฅ ํ•„๋“œ์—์„œ input ์ด๋ฒคํŠธ๊ฐ€ ์งง์€ ์‹œ๊ฐ„ ๊ฐ„๊ฒฉ์œผ๋กœ ์—ฐ์†ํ•ด์„œ ๋ฐœ์ƒํ•˜๋Š” ๊ฒฝ์šฐ๋ฅผ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

 

<!DOCTYPE html>
<html>
<body>
  <input type="text">
  <div class="msg"></div>
  <script>
    const $input = document.querySelector('input');
    const $msg = document.querySelector('.msg');

    const debounce = (callback, delay) => {
      let timerId;
      // debounce ํ•จ์ˆ˜๋Š” timerId๋ฅผ ๊ธฐ์–ตํ•˜๋Š” ํด๋กœ์ €๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
      return event => {
        // delay๊ฐ€ ๊ฒฝ๊ณผํ•˜๊ธฐ ์ด์ „์— ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ์ด์ „ ํƒ€์ด๋จธ๋ฅผ ์ทจ์†Œํ•˜๊ณ 
        // ์ƒˆ๋กœ์šด ํƒ€์ด๋จธ๋ฅผ ์žฌ์„ค์ •ํ•œ๋‹ค.
        // ๋”ฐ๋ผ์„œ delay๋ณด๋‹ค ์งง์€ ๊ฐ„๊ฒฉ์œผ๋กœ ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด callback์€ ํ˜ธ์ถœ๋˜์ง€ ์•Š๋Š”๋‹ค.
        if (timerId) clearTimeout(timerId);
        timerId = setTimeout(callback, delay, event);
      };
    };

    // debounce ํ•จ์ˆ˜๊ฐ€ ๋ฐ˜ํ™˜ํ•˜๋Š” ํด๋กœ์ €๊ฐ€ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๋กœ ๋“ฑ๋ก๋œ๋‹ค.
    // 300ms๋ณด๋‹ค ์งง์€ ๊ฐ„๊ฒฉ์œผ๋กœ input ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด debounce ํ•จ์ˆ˜์˜ ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋Š”
    // ํ˜ธ์ถœ๋˜์ง€ ์•Š๋‹ค๊ฐ€ 300ms ๋™์•ˆ input ์ด๋ฒคํŠธ๊ฐ€ ๋” ์ด์ƒ ๋ฐœ์ƒํ•˜๋ฉด ํ•œ ๋ฒˆ๋งŒ ํ˜ธ์ถœ๋œ๋‹ค.
    $input.oninput = debounce(e => {
      $msg.textContent = e.target.value;
    }, 300);
  </script>
</body>
</html>
  • ์‚ฌ์šฉ์ž๊ฐ€ ์ผ์ • ์‹œ๊ฐ„ ๋™์•ˆ ํ…์ŠคํŠธ ์ž…๋ ฅ ํ•„๋“œ์— ๊ฐ’์„ ์ž…๋ ฅํ•˜์ง€ ์•Š์œผ๋ฉด ์ž…๋ ฅ์ด ์™„๋ฃŒ๋œ ๊ฒƒ์œผ๋กœ ๊ฐ„์ฃผ
  • debounce์˜ delay ์‹œ๊ฐ„ ๋™์•ˆ input ์ด๋ฒคํŠธ๊ฐ€ ๋” ์ด์ƒ ๋ฐœ์ƒํ•˜์ง€ ์•Š์œผ๋ฉด ํ•œ ๋ฒˆ๋งŒ ํ˜ธ์ถœ

 

์ด์ฒ˜๋Ÿผ ๋””๋ฐ”์šด์Šค๋Š” resize ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ๋‚˜ input ์š”์†Œ์— ์ž…๋ ฅ๋œ ๊ฐ’์œผ๋กœ ajax ์š”์ฒญํ•˜๋Š” ์ž…๋ ฅ ํ•„๋“œ ์ž๋™์™„์„  UI ๊ตฌํ˜„, ๋ฒ„ํŠผ ์ค‘๋ณต ํด๋ฆญ ๋ฐฉ์ง€ ์ฒ˜๋ฆฌ ๋™์— ์œ ์šฉํ•˜๊ฒŒ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. Ajax ์š”์ฒญ๊ณผ ๊ฐ™์€ ๋ฌด๊ฑฐ์šด ์ฒ˜๋ฆฌ๋ฅผ ์ˆ˜ํ–‰ํ•  ๋•Œ๋Š” ์„œ๋ฒ„์— ๋ถ€๋‹ด์„ ์ฃผ์ง€ ์•Š๊ธฐ ์œ„ํ•ด ์ž…๋ ฅ์„ ์™„๋ฃŒํ–ˆ์„ ๋•Œ ํ•œ ๋ฒˆ๋งŒ Ajax ์š”์ฒญ์„ ์ „์†กํ•˜๋Š” ๊ฒƒ์ด ๋ฐ”๋žŒ์งํ•ฉ๋‹ˆ๋‹ค. (์‹ค๋ฌด์—์„œ๋Š” Underscore์˜ debounce ํ•จ์ˆ˜๋‚˜ Lodash์˜ debounce ํ•จ์ˆ˜๋ฅผ ์ฃผ๋กœ ์‚ฌ์šฉ)

 

์Šค๋กœํ‹€(throttle)

์Šค๋กœํ‹€์€ ์งง์€ ์‹œ๊ฐ„ ๊ฐ„๊ฒฉ์œผ๋กœ ์ด๋ฒคํŠธ๊ฐ€ ์—ฐ์†ํ•ด์„œ ๋ฐœ์ƒํ•˜๋”๋ผ๋„ ์ผ์ • ์‹œ๊ฐ„ ๊ฐ„๊ฒฉ์œผ๋กœ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ์ตœ๋Œ€ ํ•œ ๋ฒˆ๋งŒ ํ˜ธ์ถœ๋˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค. ์ฆ‰, ์Šค๋กœํ‹€์€ ์ด๋ฒคํŠธ๋ฅผ ๊ทธ๋ฃนํ™”ํ•ด์„œ ์ผ์ • ์‹œ๊ฐ„ ๋‹จ์œ„๋กœ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ํ˜ธ์ถœ๋˜๋„๋ก ํ˜ธ์ถœ ์ฃผ๊ธฐ๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

 

์˜ˆ๋ฅผ ๋“ค์–ด scroll ์ด๋ฒคํŠธ๊ฐ€ ์งง์€ ์‹œ๊ฐ„ ๊ฐ„๊ฒฉ์œผ๋กœ ์—ฐ์†ํ•ด์„œ ๋ฐœ์ƒํ•˜๋Š” ๊ฒฝ์šฐ๋ฅผ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

 

<!DOCTYPE html>
<html>
<head>
  <style>
    .container {
      width: 300px;
      height: 300px;
      background-color: rebeccapurple;
      overflow: scroll;
    }

    .content {
      width: 300px;
      height: 1000vh;
    }
  </style>
</head>
<body>
  <div class="container">
    <div class="content"></div>
  </div>
  <div>
    ์ผ๋ฐ˜ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ scroll ์ด๋ฒคํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•œ ํšŸ์ˆ˜:
    <span class="normal-count">0</span>
  </div>
  <div>
    ์Šค๋กœํ‹€ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ scroll ์ด๋ฒคํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•œ ํšŸ์ˆ˜:
    <span class="throttle-count">0</span>
  </div>

  <script>
    const $container = document.querySelector('.container');
    const $normalCount = document.querySelector('.normal-count');
    const $throttleCount = document.querySelector('.throttle-count');

    const throttle = (callback, delay) => {
      let timerId;
      // throttle ํ•จ์ˆ˜๋Š” timerId๋ฅผ ๊ธฐ์–ตํ•˜๋Š” ํด๋กœ์ €๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
      return event => {
        // delay๊ฐ€ ๊ฒฝ๊ณผํ•˜๊ธฐ ์ด์ „์— ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ์•„๋ฌด๊ฒƒ๋„ ํ•˜์ง€ ์•Š๋‹ค๊ฐ€
        // delay๊ฐ€ ๊ฒฝ๊ณผํ–ˆ์„ ๋•Œ ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ์ƒˆ๋กœ์šด ํƒ€์ด๋จธ๋ฅผ ์žฌ์„ค์ •ํ•œ๋‹ค.
        // ๋”ฐ๋ผ์„œ delay ๊ฐ„๊ฒฉ์œผ๋กœ callback์ด ํ˜ธ์ถœ๋œ๋‹ค.
        if (timerId) return;
        timerId = setTimeout(() => {
          callback(event);
          timerId = null;
        }, delay, event);
      };
    };

    let normalCount = 0;
    $container.addEventListener('scroll', () => {
      $normalCount.textContent = ++normalCount;
    });

    let throttleCount = 0;
    // throttle ํ•จ์ˆ˜๊ฐ€ ๋ฐ˜ํ™˜ํ•˜๋Š” ํด๋กœ์ €๊ฐ€ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๋กœ ๋“ฑ๋ก๋œ๋‹ค.
    $container.addEventListener('scroll', throttle(() => {
      $throttleCount.textContent = ++throttleCount;
    }, 100));
  </script>
</body>
</html>

 

  • throttle ํ•จ์ˆ˜๋Š” ์ด๋ฒคํŠธ๋ฅผ ๊ทธ๋ฃนํ™”ํ•ด์„œ ์ผ์ • ์‹œ๊ฐ„ ๋‹จ์œ„๋กœ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ํ˜ธ์ถœ๋˜๋„๋ก ํ˜ธ์ถœ ์ฃผ๊ธฐ๋ฅผ ๋งŒ๋“ฆ
  • throttle ํ•จ์ˆ˜์˜ ๋‘ ๋ฒˆ์งธ ์ธ์ˆ˜ delay๊ฐ€ ๊ฒฝ๊ณผํ–ˆ์„ ๋•Œ ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๊ณ  ์ƒˆ๋กœ์šด ํƒ€์ด๋จธ๋ฅผ ์žฌ์„ค์ •
  • delay ์‹œ๊ฐ„ ๊ฐ„๊ฒฉ์œผ๋กœ ์ฝœ๋ฐฑ ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ

 

์ด์ฒ˜๋Ÿผ ์ŠคํŠธ๋กค์€ scroll ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ๋‚˜ ๋ฌดํ•œ ์Šคํฌ๋กค UI ๊ตฌํ˜„ ๋“ฑ์— ์œ ์šฉํ•˜๊ฒŒ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. (์‹ค๋ฌด์—์„œ๋Š” Underscore์˜ throttle ํ•จ์ˆ˜๋‚˜ Lodash์˜ throttle ํ•จ์ˆ˜๋ฅผ ์ฃผ๋กœ ์‚ฌ์šฉ)


[์ถœ์ฒ˜] ๋ชจ๋˜ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ Deep Dive

https://wikibook.co.kr/mjs/

 

๋ชจ๋˜ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ Deep Dive: ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ๊ธฐ๋ณธ ๊ฐœ๋…๊ณผ ๋™์ž‘ ์›๋ฆฌ

269๊ฐœ์˜ ๊ทธ๋ฆผ๊ณผ ์›๋ฆฌ๋ฅผ ํŒŒํ—ค์น˜๋Š” ์„ค๋ช…์œผ๋กœ ‘์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ๊ธฐ๋ณธ ๊ฐœ๋…๊ณผ ๋™์ž‘ ์›๋ฆฌ’๋ฅผ ์ดํ•ดํ•˜์ž! ์›นํŽ˜์ด์ง€์˜ ๋‹จ์ˆœํ•œ ๋ณด์กฐ ๊ธฐ๋Šฅ์„ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ ์ œํ•œ์ ์ธ ์šฉ๋„๋กœ ํƒœ์–ด๋‚œ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” ๊ณผ๋„

wikibook.co.kr