⚛️ ๋ฆฌ์•กํŠธ ๊ฐœ๋ฐœ ํ™˜๊ฒฝ ์„ธํŒ…: CRA vs Vite

โš›๏ธ ๋ฆฌ์•กํŠธ ๊ฐœ๋ฐœ ํ™˜๊ฒฝ ์„ธํŒ…: CRA vs Vite

๐Ÿ•น️ ์—ฐํƒ€ ๊ธˆ์ง€! ์›น์‚ฌ์ดํŠธ๊ฐ€ ๋ฉˆ์ถ”์ง€ ์•Š๋Š” ๊ธฐ์ˆ : ๋””๋ฐ”์šด์Šค์™€ ์Šค๋กœํ‹€

์‡ผํ•‘๋ชฐ ๊ฒ€์ƒ‰์ฐฝ์— '์ž์ „๊ฑฐ'๋ฅผ ๊ฒ€์ƒ‰ํ•˜๋ ค๊ณ  'ใ…ˆ...ใ…...ใ…ˆ...'๋ฅผ ์ž…๋ ฅํ•  ๋•Œ๋งˆ๋‹ค ํ™”๋ฉด์ด ๊นœ๋นก๊ฑฐ๋ฆฌ๊ฑฐ๋‚˜, ๊ตฌ๋งค ๋ฒ„ํŠผ์„ ์‹ค์ˆ˜๋กœ ๋‹ค๋‹ค๋‹ฅ ๋ˆŒ๋ €๋Š”๋ฐ ๊ฒฐ์ œ๊ฐ€ ๋‘ ๋ฒˆ ๋œ ๊ฒฝํ—˜, ์žˆ์œผ์‹ ๊ฐ€์š”?
์šฐ๋ฆฌ๋Š” ๋ฌด์‹ฌ์ฝ” ํ‚ค๋ณด๋“œ์™€ ๋งˆ์šฐ์Šค๋ฅผ ๋น ๋ฅด๊ฒŒ ์กฐ์ž‘ํ•˜์ง€๋งŒ, ์ปดํ“จํ„ฐ ์ž…์žฅ์—์„œ๋Š” 0.1์ดˆ๋งˆ๋‹ค ์Ÿ์•„์ง€๋Š” ๋ช…๋ น์„ ์ „๋ถ€ ์ฒ˜๋ฆฌํ•˜๋А๋ผ '๊ณผ๋ถ€ํ•˜'๊ฐ€ ๊ฑธ๋ฆฌ๊ณค ํ•ฉ๋‹ˆ๋‹ค.

๐Ÿ’ก ํ•ต์‹ฌ ๋ฌธ์ œ:
"์‚ฌ์šฉ์ž๊ฐ€ 1์ดˆ์— 10๋ฒˆ ํด๋ฆญํ•œ๋‹ค๊ณ , ์„œ๋ฒ„์—๋„ 10๋ฒˆ ์š”์ฒญ์„ ๋ณด๋‚ด์•ผ ํ• ๊นŒ์š”?"
์ด ๋น„ํšจ์œจ์„ ๋ง‰๊ธฐ ์œ„ํ•ด ๊ฐœ๋ฐœ์ž๋“ค์€ ๋””๋ฐ”์šด์Šค(Debounce)์™€ ์Šค๋กœํ‹€(Throttle)์ด๋ผ๋Š” ๊ตํ†ต์ •๋ฆฌ ๊ธฐ์ˆ ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

์˜ค๋Š˜์€ ์ด ๋‘ ๊ฐ€์ง€ ๊ธฐ์ˆ ์ด ์–ด๋–ป๊ฒŒ ์šฐ๋ฆฌ์˜ ์›น ์„œํ•‘ ์†๋„๋ฅผ ์ง€์ผœ์ฃผ๋Š”์ง€, ๊ทธ๋ฆฌ๊ณ  ๊ฐœ๋ฐœ์ž๋“ค์€ ์ด๋ฅผ ์–ด๋–ป๊ฒŒ ๊ตฌํ˜„ํ•˜๋Š”์ง€(React/Vue) ์•„์ฃผ ์‰ฝ๊ฒŒ ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.


๐Ÿšช 1. ์—˜๋ฆฌ๋ฒ ์ดํ„ฐ์˜ ์ง€ํ˜œ: ๋””๋ฐ”์šด์Šค (Debounce)

๋””๋ฐ”์šด์Šค(Debounce)๋Š” "๋งˆ์ง€๋ง‰ ํ–‰๋™์ด ๋๋‚  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ ค์ฃผ๋Š” ๊ธฐ์ˆ "์ž…๋‹ˆ๋‹ค.
๊ฐ€์žฅ ์‰ฌ์šด ์˜ˆ๋กœ ์—˜๋ฆฌ๋ฒ ์ดํ„ฐ ๋ฌธ์„ ์ƒ๊ฐํ•ด๋ณด์„ธ์š”.

  • ๐Ÿƒ ์ƒํ™ฉ: ์—˜๋ฆฌ๋ฒ ์ดํ„ฐ ๋ฌธ์ด ๋‹ซํžˆ๋ ค๊ณ  ํ•˜๋Š”๋ฐ ์ € ๋ฉ€๋ฆฌ์„œ ์‚ฌ๋žŒ์ด ๋‹ฌ๋ ค์˜ต๋‹ˆ๋‹ค.
  • ๐Ÿ”˜ ํ–‰๋™: '์—ด๋ฆผ' ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด ๋ฌธ์ด ๋‹ค์‹œ ์—ด๋ฆฌ๊ณ  ๋‹ซํžˆ๋Š” ์‹œ๊ฐ„์ด ์ดˆ๊ธฐํ™”๋ฉ๋‹ˆ๋‹ค.
  • ๊ฒฐ๊ณผ: ๋งˆ์ง€๋ง‰์œผ๋กœ ํƒ‘์Šนํ•œ ์‚ฌ๋žŒ์ด ๋“ค์–ด์˜ค๊ณ  ๋‚˜์„œ, ์ผ์ • ์‹œ๊ฐ„์ด ์ง€๋‚˜์•ผ ๋น„๋กœ์†Œ ๋ฌธ์ด ๋‹ซํžˆ๊ณ  ์ถœ๋ฐœํ•ฉ๋‹ˆ๋‹ค.

์›น์‚ฌ์ดํŠธ์˜ ๊ฒ€์ƒ‰์ฐฝ์ด ๋ฐ”๋กœ ์ด ์›๋ฆฌ์ž…๋‹ˆ๋‹ค.
์—ฌ๋Ÿฌ๋ถ„์ด '์ž์ „๊ฑฐ'๋ฅผ ์น  ๋•Œ 'ใ…ˆ', '์ž', '์žฉ'.. ์ž…๋ ฅํ•  ๋•Œ๋งˆ๋‹ค ๊ฒ€์ƒ‰ํ•˜๋Š” ๊ฒŒ ์•„๋‹ˆ๋ผ, ์ž…๋ ฅ์ด ๋”ฑ ๋ฉˆ์ถ”๋Š” ์ˆœ๊ฐ„(๋งˆ์ง€๋ง‰ ํƒ€์ž)์— ํ•œ ๋ฒˆ๋งŒ ๊ฒ€์ƒ‰์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.
๋•๋ถ„์— ๋ฐ์ดํ„ฐ ๋‚ญ๋น„๋ฅผ ๋ง‰์„ ์ˆ˜ ์žˆ์ฃ .

๐Ÿ’ป ๊ฐœ๋ฐœ์ž๋Š” ์ด๋ ‡๊ฒŒ ๋งŒ๋“ค์–ด์š” (React Hook ์˜ˆ์‹œ)
// ์‚ฌ์šฉ์ž์˜ ์ž…๋ ฅ์ด ๋ฉˆ์ถ”๋ฉด delay ์‹œ๊ฐ„ ๋’ค์— ๊ฐ’์„ ๋ฐ”๊ฟ”์ฃผ๋Š” ๋งˆ๋ฒ• ์ƒ์ž
function useDebounce(value, delay) {
  const [debouncedValue, setDebouncedValue] = useState(value);

  useEffect(() => {
    // ํƒ€์ด๋จธ ์„ค์ •: delay ์‹œ๊ฐ„์ด ์ง€๋‚˜๋ฉด ๊ฐ’ ๋ณ€๊ฒฝ
    const handler = setTimeout(() => {
      setDebouncedValue(value);
    }, delay);

    // ๋งŒ์•ฝ ์‹œ๊ฐ„์ด ๋˜๊ธฐ ์ „์— ๋˜ ์ž…๋ ฅํ•˜๋ฉด? ๊ธฐ์กด ํƒ€์ด๋จธ ์ทจ์†Œ! (ํ•ต์‹ฌ)
    return () => {
      clearTimeout(handler);
    };
  }, [value, delay]);

  return debouncedValue;
}

๐Ÿš‡ 2. ์ •ํ•ด์ง„ ์‹œ๊ฐ„์—๋งŒ ์ถœ๋ฐœ: ์Šค๋กœํ‹€ (Throttle)

์Šค๋กœํ‹€(Throttle)์€ "์•„๋ฌด๋ฆฌ ์š”์ฒญ์ด ๋งŽ์•„๋„ ์ •ํ•ด์ง„ ์‹œ๊ฐ„ ๊ฐ„๊ฒฉ์œผ๋กœ๋งŒ ์‹คํ–‰ํ•˜๋Š” ๊ธฐ์ˆ "์ž…๋‹ˆ๋‹ค.
์ด๋ฒˆ์—๋Š” ์ง€ํ•˜์ฒ ์„ ๋– ์˜ฌ๋ ค๋ณด์„ธ์š”.

์Šน๊ฐ์ด ์•„๋ฌด๋ฆฌ ๋งŽ์ด ๋ชฐ๋ ค์™€๋„, ์ง€ํ•˜์ฒ ์€ ์ •ํ•ด์ง„ ์‹œ๊ฐ„ํ‘œ(์˜ˆ: 5๋ถ„ ๊ฐ„๊ฒฉ)์— ๋งž์ถฐ์„œ๋งŒ ์ถœ๋ฐœํ•ฉ๋‹ˆ๋‹ค.
์ค‘๊ฐ„์— ์Šน๊ฐ์ด ๋” ํƒ„๋‹ค๊ณ  ํ•ด์„œ ๋ฐ”๋กœ ์ถœ๋ฐœํ•˜์ง€๋„, ๋Šฆ๊ฒŒ ์ถœ๋ฐœํ•˜์ง€๋„ ์•Š์ฃ .
์ด ๊ธฐ์ˆ ์€ ์Šคํฌ๋กค ๊ธฐ๋Šฅ์— ์ฃผ๋กœ ์“ฐ์ž…๋‹ˆ๋‹ค. ์Šคํฌ๋กค์„ 1์ดˆ์— 100๋ฒˆ ๋‚ด๋ ค๋„, ์ปดํ“จํ„ฐ๋Š” 0.1์ดˆ์— ํ•œ ๋ฒˆ์”ฉ๋งŒ ํ™”๋ฉด ์œ„์น˜๋ฅผ ๊ณ„์‚ฐํ•ด์„œ ๋ฒ„๋ฒ…๊ฑฐ๋ฆผ์„ ๋ฐฉ์ง€ํ•ฉ๋‹ˆ๋‹ค.

๐Ÿ’ป ๊ฐœ๋ฐœ์ž๋Š” ์ด๋ ‡๊ฒŒ ๋งŒ๋“ค์–ด์š” (React Hook ์˜ˆ์‹œ)
// ์•„๋ฌด๋ฆฌ ํ˜ธ์ถœํ•ด๋„ interval ์‹œ๊ฐ„ ๊ฐ„๊ฒฉ์œผ๋กœ๋งŒ ์‹คํ–‰๋˜๋Š” ๋งˆ๋ฒ• ์ƒ์ž
function useThrottle(value, interval) {
  const [throttledValue, setThrottledValue] = useState(value);
  const lastRan = useRef(Date.now());

  useEffect(() => {
    const handler = setTimeout(() => {
      if (Date.now() - lastRan.current >= interval) {
        setThrottledValue(value);
        lastRan.current = Date.now();
      }
    }, interval - (Date.now() - lastRan.current));

    return () => clearTimeout(handler);
  }, [value, interval]);

  return throttledValue;
}

⚖️ 3. ํ•œ๋ˆˆ์— ๋ณด๋Š” ์ฐจ์ด์ 

๋‘ ๊ธฐ์ˆ  ๋ชจ๋‘ "์ปดํ“จํ„ฐ๋ฅผ ์‰ฌ๊ฒŒ ํ•ด์ค€๋‹ค"๋Š” ์ ์€ ๊ฐ™์ง€๋งŒ, ์‚ฌ์šฉ ๋ชฉ์ ์ด ์กฐ๊ธˆ ๋‹ค๋ฆ…๋‹ˆ๋‹ค.
ํ—ท๊ฐˆ๋ฆฌ์‹ ๋‹ค๋ฉด ์•„๋ž˜ ํ‘œ๋งŒ ๊ธฐ์–ตํ•˜์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค.

๊ตฌ๋ถ„ ๋””๋ฐ”์šด์Šค (Debounce) ์Šค๋กœํ‹€ (Throttle)
๋น„์œ  ์—˜๋ฆฌ๋ฒ ์ดํ„ฐ (๊ธฐ๋‹ค๋ฆผ) ์ง€ํ•˜์ฒ  (์‹œ๊ฐ„ํ‘œ ์ค€์ˆ˜)
ํ•ต์‹ฌ ์›๋ฆฌ ๋งˆ์ง€๋ง‰ ํ–‰๋™ ํ›„ ์‹คํ–‰ ์ผ์ • ์‹œ๊ฐ„๋งˆ๋‹ค ์‹คํ–‰
์ฃผ ์‚ฌ์šฉ์ฒ˜ ๊ฒ€์ƒ‰์–ด ์ž…๋ ฅ, ์ฐฝ ํฌ๊ธฐ ์กฐ์ ˆ ๋ ์Šคํฌ๋กค ๋‚ด๋ฆฌ๊ธฐ, ๋งˆ์šฐ์Šค ์ด๋™

๐Ÿ’ก Vue ์‚ฌ์šฉ์ž๋ผ๋ฉด?
์œ„์˜ ์˜ˆ์‹œ๋Š” React์˜ 'Hook'์ด๋ผ๋Š” ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค.
Vue.js๋ฅผ ์‚ฌ์šฉํ•˜์‹ ๋‹ค๋ฉด 'Composables'๋ผ๋Š” ๋น„์Šทํ•œ ๋ฐฉ์‹์„ ํ†ตํ•ด, ๋˜‘๊ฐ™์€ ๋กœ์ง(setTimeout ํ™œ์šฉ)์œผ๋กœ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
๋„๊ตฌ์˜ ์ด๋ฆ„๋งŒ ๋‹ค๋ฅผ ๋ฟ, ์„ฑ๋Šฅ์„ ์ตœ์ ํ™”ํ•˜๋Š” ์›๋ฆฌ๋Š” ๋งŒ๊ตญ ๊ณตํ†ต์ด๋ž๋‹ˆ๋‹ค.

✨๋ณด์ด์ง€ ์•Š๋Š” ๊ณณ์˜ ๋ฐฐ๋ ค

์šฐ๋ฆฌ๊ฐ€ ๋งค์ผ ์“ฐ๋Š” ์›น์‚ฌ์ดํŠธ๋‚˜ ์•ฑ์ด ๋ถ€๋“œ๋Ÿฝ๊ฒŒ ๋А๊ปด์ง€๋Š” ์ด์œ ๋Š”, ๋‹จ์ˆœํžˆ ์ธํ„ฐ๋„ท์ด ๋นจ๋ผ์„œ๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค.
๋ณด์ด์ง€ ์•Š๋Š” ๊ณณ์—์„œ ๋””๋ฐ”์šด์Šค์™€ ์Šค๋กœํ‹€ ๊ฐ™์€ ๊ธฐ์ˆ ๋“ค์ด ๋Š์ž„์—†์ด ๊ตํ†ต์ •๋ฆฌ๋ฅผ ํ•ด์ฃผ๋ฉฐ ๋ฐ์ดํ„ฐ๋ฅผ ์•„๊ปด์ฃผ๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

ํ˜น์‹œ ๋‚˜์ค‘์— ์–ด๋–ค ์‚ฌ์ดํŠธ์—์„œ ๊ฒ€์ƒ‰์–ด๋ฅผ ๋ง‰ ์ž…๋ ฅํ–ˆ๋Š”๋ฐ๋„ ๋ ‰์ด ๊ฑธ๋ฆฌ์ง€ ์•Š๋Š”๋‹ค๋ฉด,
"์•„, ์—ฌ๊ธฐ ๊ฐœ๋ฐœ์ž๊ฐ€ ๋””๋ฐ”์šด์Šค ์ฒ˜๋ฆฌ๋ฅผ ์ž˜ ํ•ด๋†จ๊ตฌ๋‚˜!" ํ•˜๊ณ  ์ƒ๊ฐํ•ด๋ณด์‹œ๋Š” ๊ฑด ์–ด๋–จ๊นŒ์š”?
์ž‘์€ ๊ธฐ์ˆ ์˜ ์ฐจ์ด๊ฐ€ ๋ช…ํ’ˆ ์„œ๋น„์Šค๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

๋Œ“๊ธ€ ์“ฐ๊ธฐ