Front-end/JS

์ง์ ‘ ๊ตฌํ˜„ํ•˜๋ฉฐ ๋Š๋‚€ Debounce ์™€ Throttle ์ฐจ์ด

ciocio 2024. 11. 18. 11:12

๐Ÿ“Œ  Debounce ? Throttle ?  ๊ณต๋ถ€ํ•˜๊ฒŒ ๋œ ์ด์œ 

 

resize ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ํ†ตํ•ด ํ™”๋ฉด์˜ ์‚ฌ์ด์ฆˆ ๋ณ€๊ฒฝ์„ ๊ฐ์ง€ํ•˜๊ณ 

๊ทธ์— ๋”ฐ๋ผ ํ™”๋ฉด์˜ ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ๋ณ€๊ฒฝํ•ด์•ผํ•˜๋Š” ๊ธฐ๋Šฅ์ด ์žˆ์—ˆ๋‹ค.

๊ทธ๋Ÿฐ๋ฐ ์ •๋ง๋กœ ํ™”๋ฉด ํฌ๊ธฐ๊ฐ€ ๋ฐ”๋€” ๋•Œ๋งˆ๋‹ค ๋งค๋ฒˆ ์ด๋ฒคํŠธ๊ฐ€ ํ˜ธ์ถœ๋˜๋Š” ๊ฑธ ๋ณด๊ณ 

๋ฆฌํŽ˜์ธํŠธ ๋น„์šฉ ๋‚ญ๋น„๊ฐ€ ์˜ˆ์ƒ๋˜์—ˆ๋‹ค.

๋งˆ์šฐ์Šค๋กœ ์š”๋ฆฌ์กฐ๋ฆฌ ๋ณ€๊ฒฝํ•  ๋•Œ๋งˆ๋‹ค ์ด๋ฒคํŠธ๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ฒŒ ์•„๋‹ˆ๋ผ

๋ณ€๊ฒฝ์ด ๋๋‚œ ํ›„ ํ™”๋ฉด ์‚ฌ์ด์ฆˆ๊ฐ€ ๊ณ ์ •๋˜์—ˆ์„ ๋•Œ ํ•œ๋ฒˆ๋งŒ ํ˜ธ์ถœํ•˜๋„๋ก ์ˆ˜์ •ํ•˜๊ณ  ์‹ถ์—ˆ๋‹ค.

์ตœ์ ํ™” ๋ฐฉ๋ฒ• ์ค‘ ์ผ๋ถ€์ธ, Debounce ์™€ Throttle ์„ ๊ณต๋ถ€ํ•ด๋ณด์ž.

 

Debounce ์™€ Throttle ๋ชจ๋‘ ํ•จ์ˆ˜์˜ ์—ฐ์†์ ์ธ ์‹คํ–‰์„ ์ œํ•œํ•˜๋Š” ๋ชฉ์ ์„ ๊ฐ€์ง€๊ณ  ์„ค๊ณ„๋˜์—ˆ๋‹ค.

 

 

๐Ÿ“  Debounce

์š”์ฒญ์ด ๋“ค์–ด์˜จ ๋’ค, ์ผ์ • ์‹œ๊ฐ„์„ ๊ธฐ๋‹ค๋ฆฐ ํ›„ ์š”์ฒญ์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.
์ผ์ • ์‹œ๊ฐ„ ๋‚ด์— ๊ฐ™์€ ์š”์ฒญ์ด ์ถ”๊ฐ€๋กœ ๋“ค์–ด์˜ค๋ฉด ์ด์ „ ์š”์ฒญ์€ ์ทจ์†Œ๋œ๋‹ค.

 

const debounce = (func, timeout = 300) => {
  let timerID;
  return (...args) => {
    clearTimeout(timerID);
    timerID = setTimeout(() => {
      func(...args);
    }, timeout);
  };
};

 

์ฝ”๋“œ๋ฅผ ๋ณด๋ฉด, ๋‚ด๊ฐ€ ์‹คํ–‰์‹œํ‚ค๊ณ  ์‹ถ์€ ํ•จ์ˆ˜์™€ ์ผ์ • ์‹œ๊ฐ„์„ ์ฐจ๋ก€๋กœ ์ž…๋ ฅ๋ฐ›๋Š”๋‹ค.

timer ๋ณ€์ˆ˜๋Š” setTimeout ํ•จ์ˆ˜๋ฅผ ์—ฐ์†ํ•ด์„œ ํ• ๋‹น๋ฐ›๋Š”๋‹ค.

clearTimeout ์€ setTimeout ๋น„๋™๊ธฐ ํ•จ์ˆ˜์˜ ํ˜ธ์ถœ์„ ์ทจ์†Œํ•˜๋Š” ์—ญํ• ์„ ํ•œ๋‹ค.

 

์ผ์ • ์‹œ๊ฐ„ ๋‚ด์— debounce ํ•จ์ˆ˜๋ฅผ ๊ณ„์† ํ˜ธ์ถœํ–ˆ์„ ๋•Œ, 

timerID ๋ณ€์ˆ˜์— ๊ณ„์† ์ƒˆ๋กœ์šด setTimeout ํ•จ์ˆ˜๊ฐ€ ํ• ๋‹น๋œ๋‹ค.

์ผ์ • ์‹œ๊ฐ„์ด ์ง€๋‚˜๊ณ  timerID ๊ฐ€ ๋” ์ด์ƒ ์ดˆ๊ธฐํ™”๋˜์ง€ ์•Š์„ ๋•Œ,
๊ทธ์ œ์„œ์•ผ setTimeout ๋‚ด ๋น„๋™๊ธฐ ํ•จ์ˆ˜๊ฐ€ ์‹คํ–‰๋œ๋‹ค.

์ด๋•Œ ์ธ์ž๋กœ ๋ฐ›์€ ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋œ๋‹ค. (1๋ฒˆ)

 

์กฐ๊ธˆ ๋” ์ž์„ธํžˆ ์„ค๋ช…ํ•˜์ž๋ฉด,

setTimeout ์„ ํ˜ธ์ถœํ•˜๋ฉด Timer Identifier (ํƒ€์ด๋จธ ์‹๋ณ„์ž) ๊ฐ€ ๋ฐ˜ํ™˜๋œ๋‹ค.

(timerID ๋ณ€์ˆ˜์— ์‹ค์ œ๋กœ ๋‹ด๊ฒจ์žˆ๋Š” ๊ฐ’)

๊ทธ๋ž˜์„œ clearTimeout(ํƒ€์ด๋จธ ์‹๋ณ„์ž) ๋ฅผ ํ˜ธ์ถœํ–ˆ์„ ๋•Œ 

setTimeout ๋‚ด ๋น„๋™๊ธฐ ํ•จ์ˆ˜์˜ ์‹คํ–‰์„ ์ทจ์†Œํ•  ์ˆ˜ ์žˆ๋‹ค.

 

 

โœ… Trailing vs Leading

 

https://llu.is/throttle-and-debounce-visualized

ํ•จ์ˆ˜๊ฐ€ ๋‚˜์ค‘์— ์‹คํ–‰๋˜๋Š”์ง€, ์ฒ˜์Œ์— ์‹คํ–‰๋˜๋Š”์ง€ ์—ฌ๋ถ€์— ๋”ฐ๋ผ Debounce ๋ฅผ ๊ตฌ๋ถ„ํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

 

1๏ธโƒฃ Trailing Debounce

 

const debounce = (func, timeout = 300) => {
  let timerID;
  return (...args) => {
    clearTimeout(timerID);
    timerID = setTimeout(() => {
      func(...args);
    }, timeout);
  };
};

 

์œ„ ์ฝ”๋“œ์™€ ๋™์ผํ•˜๋‹ค.

๋งค๋ฒˆ ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•  ๋•Œ๋งˆ๋‹ค ์ง€์ •ํ•œ timeout ๋งŒํผ ๊ธฐ๋‹ค๋ฆฌ๊ธฐ ๋•Œ๋ฌธ์—

๋งˆ์ง€๋ง‰์— ๋ฐœ์ƒํ•œ ์ด๋ฒคํŠธ๋„ ์ผ์ • ์‹œ๊ฐ„ ๊ธฐ๋‹ค๋ฆฐ ๋งŒํผ ์‹คํ–‰๋œ๋‹ค.

 

2๏ธโƒฃ Leading Debounce

 

const debounce = (func, timeout = 300) => {
  let timerID;
  return (...args) => {
  	if (!timerID) {
    	func(...args);
    }
    clearTimeout(timerID);
    timerID = setTimeout(() => {
      timerID = undefined;
    }, timeout);
  };
};

 

์ด๋ฒคํŠธ ๋ฐœ์ƒ์‹œ ์ฒ˜์Œ ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋˜๊ณ  ์ดํ›„์˜ ํ•จ์ˆ˜ ํ˜ธ์ถœ์€ ๋ชจ๋‘ ๋ฌด์‹œํ•œ๋‹ค.

 

 

๐Ÿ“  Throttle

์ผ์ • ์‹œ๊ฐ„ ๋™์•ˆ ์š”์ฒญ์ด ํ•œ ๋ฒˆ๋งŒ ์ˆ˜ํ–‰ํ•œ๋‹ค.

 

 

 

 

Devounce vs Throttle visualization

๋””๋ฐ”์šด์‹ฑ๊ณผ ํŠธ๋กœํ‹€๋ง ์‹œ๊ฐํ™”๋ฅผ ์ž˜ ํ•ด๋†“์€ ๋ธ”๋กœ๊ทธ๊ฐ€ ์žˆ์–ด ์ฒจ๋ถ€ํ•œ๋‹ค.

๋ฐ˜์‘ํ˜•