๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

react

React / Debounce, Throttle

 

Debounce & Throttle

์—ฐ์†์ ์œผ๋กœ ๋ฐœ์ƒํ•˜๋Š” ํ•จ์ˆ˜๋‚˜ ์ด๋ฒคํŠธ์˜ ์‹คํ–‰ ๋นˆ๋„๋ฅผ ์ค„์ด๊ธฐ ์œ„ํ•ด ๋ฌถ์–ด์„œ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ธฐ๋ฒ•์œผ๋กœ, ์ตœ์ ํ™”๋ฅผ ํ†ตํ•œ ์„ฑ๋Šฅ ํ–ฅ์ƒ์ด ๋ชฉ์ ์ด๋‹ค.

 

 

Debounce vs Thottle

 

1) ํ•จ์ˆ˜๋‚˜ ์ด๋ฒคํŠธ๊ฐ€ ์—ฐ์†์ ์œผ๋กœ ๋ฐœ์ƒํ•˜๋Š” ๊ฒฝ์šฐ

์ถœ์ฒ˜ : ์˜ค์ฆˆ์ฝ”๋”ฉ์Šค์ฟจ

 

2) ํ•จ์ˆ˜๋‚˜ ์ด๋ฒคํŠธ๊ฐ€ ์—ฐ์†์ ์ด ์•„๋‹Œ ๋Š์–ด์„œ ๋ฐœ์ƒํ•˜๋Š” ๊ฒฝ์šฐ

 

์ถœ์ฒ˜ : ์˜ค์ฆˆ์ฝ”๋”ฉ์Šค์ฟจ


Debounce : ์—ฐ์†์ ์œผ๋กœ ํ•จ์ˆ˜๋‚˜ ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒ ํ›„ ์ผ์ • ์‹œ๊ฐ„ ๋™์•ˆ ์ถ”๊ฐ€ ์ด๋ฒคํŠธ/ํ•จ์ˆ˜๊ฐ€ ์—†๋‹ค๋ฉด ์‹คํ–‰

Throttle : ์—ฐ์†์ ์œผ๋กœ ํ•จ์ˆ˜๋‚˜ ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๋™์•ˆ ์ผ์ • ์‹œ๊ฐ„ ๊ฐ„๊ฒฉ(ํ…€์„ ๊ฐ€์ง€๊ณ )์œผ๋กœ ์‹คํ–‰ 

 

 

 


 

 

 

Debounce

์—ฐ์†์ ์œผ๋กœ ๋ฐœ์ƒํ•œ ์ด๋ฒคํŠธ๋ฅผ ํ•˜๋‚˜๋กœ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ, ๋งˆ์ง€๋ง‰์— ํ•œ ๋ฒˆ์— ๋ฌถ์–ด์„œ ์ฒ˜๋ฆฌํ•ด๋„ ์ƒ๊ด€ ์—†์„ ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค.

๊ฒ€์ƒ‰ ์ž๋™ ์™„์„ฑ ๊ฐ™์€ ์‚ฌ์šฉ์ž ์ž…๋ ฅ ์ฒ˜๋ฆฌ์— ์œ ์šฉํ•˜๋‹ค.

 

 

์˜ˆ์‹œ

์ด๋ฒˆ์—๋„ ์ด์ „์— ์‹ค์Šตํ•œ ๋™๋ฌผ ์ •๋ณด ์‚ฌ์ดํŠธ๋ฅผ ๊ฐ€์ ธ์™”๋‹ค... https://hydeveloper.tistory.com/195

์ผ๋‹จ Debounce๋ฅผ ์“ฐ๊ธฐ์— ์•ž์„œ ์‚ด์ง ์ฝ”๋“œ๋ฅผ ์ˆ˜์ •ํ•ด์„œ ๊ฒ€์ƒ‰์–ด๊ฐ€ ์ž…๋ ฅ๋ ๋•Œ๋งˆ๋‹ค ๋ฐ”๋กœ ๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์˜ค๋„๋ก ํ–ˆ๋‹ค.

 

App.jsx์˜ ์ผ๋ถ€

<input
  value={inputValue}
  onChange={(event) => {
    setInputValue(event.target.value);
    // inputValue๊ฐ€ ์•„๋‹Œ event.target.value๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ด์œ 
    // inputValue๋Š” ๋ณ€๊ฒฝ๋˜๊ธฐ ์ด์ „์˜ ์ƒํƒœ์—ฌ์„œ ๋งŒ์•ฝ ์•„๋ž˜ ์ฃผ์†Œ์— inputvalue๋ฅผ ๋„ฃ์„ ๊ฒฝ์šฐ
    // ๊ธฐ์กด ํ‚ค์›Œ๋“œ์—์„œ ์ž„์˜๋กœ ์ž…๋ ฅ์„ ํ•œ๋ฒˆ ๋” ํ•ด์•ผ๋งŒ ๊ทธ ๊ฒ€์ƒ‰์–ด ๊ฒฐ๊ณผ๊ฐ€ ๋ฐ˜์˜๋œ๋‹ค... (ํ•œ๋‹จ๊ณ„ ๋А๋ฆฌ๊ฒŒ url์ด ์—…๋ฐ์ดํŠธ๋จ)
    navigate(`/search?animal=${event.target.value}`);
  }}
/>
<button onClick={() => navigate(`/search?animal=${inputValue}`)}>
  ๊ฒ€์ƒ‰
</button>

 

Search.jsx์˜ ์ผ๋ถ€

const [searchParams] = useSearchParams();
const param = searchParams.get("animal");
const reg = getRegExp(param);
const filteredData = data.filter((el) => el.name.match(reg));

 

์ด๋ ‡๊ฒŒ ํ•  ๊ฒฝ์šฐ.. 

๋งŒ์•ฝ ๋‚ด๊ฐ€ 'ํŒ๋‹ค'๋ฅผ ์ž…๋ ฅํ•˜๊ณ ์ž ํ•œ๋‹ค๋ฉด ์˜คํƒ€๊ฐ€ ์—†๋‹ค๋Š” ๊ฐ€์ •ํ•˜์— ใ… ใ… ใ„ด ใ„ท ใ… ์ตœ์†Œ ๋‹ค์„ฏ๋ฒˆ์€ ์„œ๋ฒ„ ์š”์ฒญ์„ ๋ณด๋‚ด์•ผ ํ•œ๋‹ค. ์ด๋Ÿฐ ์‹์˜ ๊ฒ€์ƒ‰ ์ด๋ฒคํŠธ๊ฐ€ ์ˆ˜์ฐจ๋ก€ ๋ฐœ์ƒ๋œ๋‹ค๋ฉด ์ ์–ด๋„ ์„œ๋ฒ„๋‚˜ ์ฒญ๊ตฌ์„œ ๋‘˜ ์ค‘ ํ•˜๋‚˜๋Š” ํ„ฐ์งˆ ์ˆ˜ ์žˆ๋‹ค...

 

 

์ด์ œ Debounce๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์ˆ˜์ •ํ•  ๊ฑด๋ฐ, ์•„๋ฌด๋ž˜๋„ ์ผ์ • ์‹œ๊ฐ„์ด ์ง€๋‚œ ํ›„์— ํ•จ์ˆ˜/์ด๋ฒคํŠธ๋ฅผ ์ˆ˜ํ–‰ํ•˜๊ธฐ ๋•Œ๋ฌธ์— setTimeout๊ฐ™์€ ํƒ€์ด๋จธ ํ•จ์ˆ˜๊ฐ€ ํ•„์š”ํ•˜๋‹ค.

 

  const [searchParams] = useSearchParams();
  const param = searchParams.get('animal');
  const reg = getRegExp(param);

  // filteredData๊ฐ€ ๋ณ€๊ฒฝ๋  ๋•Œ debounce๋ฅผ ์‹คํ–‰ํ•˜๊ธฐ ์œ„ํ•ด ์ƒˆ๋กœ์šด ์ƒํƒœ ์ƒ์„ฑ
  const [filteredData, setFilteredData] = useState(data);
  useEffect(() => {
    const debounceTimer = setTimeout(() => {
      const newFilteredData = data.filter((el) => el.name.match(reg));
      setFilteredData(newFilteredData);
    }, 1000); // 1์ดˆ ๋™์•ˆ ์ถ”๊ฐ€ ์ž…๋ ฅ์ด ์ผ์–ด๋‚˜์ง€ ์•Š์œผ๋ฉด ๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ๋ฅผ ๋ณด์—ฌ์คŒ
    return () => clearTimeout(debounceTimer);
  }, [param]);

 

  • param์ด ๋ฐ”๋€” ๋•Œ๋งˆ๋‹ค useEffect๊ฐ€ ์‹คํ–‰
  • setTimeout์œผ๋กœ 1์ดˆ ๋’ค์— ํ•„ํ„ฐ๋ง ์ˆ˜ํ–‰
    => ๊ทธ๋Ÿฌ๋‚˜ 1์ดˆ ์•ˆ์œผ๋กœ ๋‹ค๋ฅธ param์ด ์ž…๋ ฅ๋˜๋ฉด ์ด์ „ ํƒ€์ด๋จธ๋ฅผ ํด๋ฆฌ์–ดํ•จ์ˆ˜๋กœ ์ œ๊ฑฐ
    => 1์ดˆ ๋’ค์—๋„ param์ด ๋ฐ”๋€Œ์ง€ ์•Š๋Š”๋‹ค๋ฉด ๊ฒ€์ƒ‰ ํ•„ํ„ฐ๋ง ์‹คํ–‰ 
  • ์œ„ ์˜ˆ์‹œ์—์„œ Debounce๋Š” ์ž…๋ ฅ์ด ๋ฉˆ์ถ˜ ๋’ค, 1์ดˆ๊ฐ€ ์ง€๋‚˜์„œ ์‹คํ–‰๋˜๋Š” ๊ตฌ์กฐ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค.

 

 

 

 


 

 

Throttle

์ด๋ฒคํŠธ๋ฅผ ์ผ์ • ์ฃผ๊ธฐ๋งˆ๋‹ค ๋ฐœ์ƒํ•˜๋„๋ก ํ•˜๋Š” ๊ธฐ์ˆ ๋กœ, ์ค‘๊ฐ„ ์ค‘๊ฐ„ ๋Š๊ธฐ์ง€ ์•Š๋Š” ์ธํ„ฐ๋ž™์…˜์ด ํ•„์š”ํ•  ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค.

๋งˆ์šฐ์Šค ์ด๋™, ์Šคํฌ๋กค ์ด๋ฒคํŠธ๊ฐ™์ด ๋นˆ๋ฒˆํ•˜๊ฒŒ ๋ฐœ์ƒํ•˜๋Š” ์ด๋ฒคํŠธ๋ฅผ ์ฒ˜๋ฆฌ ์‹œ ์œ ์šฉํ•˜๋‹ค.

 

 

์˜ˆ์‹œ

 

์œ„์˜ ๋™๋ฌผ ์ •๋ณด ์‚ฌ์ดํŠธ๋ฅผ ์ด๋ฒˆ์—” throttle ๋ฐฉ์‹์œผ๋กœ ๋ฐ”๊ฟ”์„œ ์‚ฌ์šฉํ•  ๊ฒƒ์ด๋‹ค.

 

์ผ์ • ์‹œ๊ฐ„๋งˆ๋‹ค ์‹คํ–‰๋˜๋Š” ๋งŒํผ ์‹œ๊ฐ„ ์ •๋ณด๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๊ฐ์ฒด๋ฅผ ๋”ฐ๋กœ ๋งŒ๋“ค์–ด์ค˜์•ผ ํ•˜๋Š”๋ฐ, ์ด ์˜ˆ์‹œ์—์„œ๋Š” ๋‚จ์€ ์‹œ๊ฐ„์„ ๊ณ„์‚ฐํ•ด ์ง€์—ฐ์‹œํ‚ค๋Š” ๋ฐฉ์‹์œผ๋กœ ๊ตฌํ˜„ํ•˜๊ณ  ์žˆ๋‹ค.

์˜ˆ์‹œ์—์„œ๋Š” 1์ดˆ๋งˆ๋‹ค ์‹คํ–‰ํ•˜๋ฏ€๋กœ setTimeout์˜ ๋งค๊ฐœ๋ณ€์ˆ˜ ์ค‘ delay ๋ถ€๋ถ„์„

1000- (ํ˜„์žฌ ์‹œ๊ฐ„ - ์ด์ „ ์‹คํ–‰ ์‹œ๊ฐ„)์œผ๋กœ ์ž‘์„ฑํ•ด 1์ดˆ๋งˆ๋‹ค ์‹คํ–‰๋  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ๊ฒƒ์ด ํ•ต์‹ฌ์ด๋‹ค.... 

๊ฐ•์˜์—์„œ time ๊ณ„์‚ฐ ๋ฐฉ์‹์„ ์„ค๋ช…ํ•ด์ฃผ์‹œ๊ธฐ ์œ„ํ•ด ์ž‘์„ฑํ•ด์ฃผ์‹  ์˜ˆ์‹œ

 

  const [searchParams] = useSearchParams();
  const param = searchParams.get('animal');
  const reg = getRegExp(param);
  // filteredData๊ฐ€ ๋ณ€๊ฒฝ๋  ๋•Œ debounce๋ฅผ ์‹คํ–‰ํ•˜๊ธฐ ์œ„ํ•ด ์ƒˆ๋กœ์šด ์ƒํƒœ ์ƒ์„ฑ
  const [filteredData, setFilteredData] = useState(data);

  // ์ด์ „ ์‹คํ–‰ ์‹œ๊ฐ„์„ ๊ธฐ์–ตํ•ด๋‘๋Š” ๋ณ€์ˆ˜
  // useRef๋Š” ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ฆฌ๋ Œ๋”ฉ๋ผ๋„ ๊ฐ’์ด ์œ ์ง€๋˜๊ธฐ ๋•Œ๋ฌธ์— ์‚ฌ์šฉ!!
  const time = useRef(new Date());

  useEffect(() => {
    // ํ˜„์žฌ ์‹œ๊ฐ„, time.current์™€ ๋น„๊ตํ•ด์„œ ์–ผ๋งˆ๋‚˜ ์‹œ๊ฐ„์ด ํ˜๋ €๋Š”์ง€ ์ธก์ •์„ ์œ„ํ•จ
    const newTime = new Date();
    
    const throttleTimer = setTimeout(() => {
      const newFilteredData = data.filter((el) => el.name.match(reg));
      setFilteredData(newFilteredData);
      // ์‹คํ–‰๋˜์—ˆ์œผ๋‹ˆ ํ˜„์žฌ ์‹œ๊ฐ์œผ๋กœ ๊ฐฑ์‹ 
      time.current = new Date();
      // ๋งˆ์ง€๋ง‰ ์‹คํ–‰์ด 0.6์ดˆ ์ „์ด๋ผ๋ฉด, 1000 - 600 = 400ms ํ›„์— ์‹คํ–‰๋˜๋„๋ก ์˜ˆ์•ฝ
      // ์ฆ‰ 1์ดˆ์— ํ•œ๋ฒˆ๋งŒ ์‹คํ–‰๋˜๋„๋ก ํ•จ
    }, 1000 - (newTime - time.current));
    // ํด๋ฆฌ์–ด ํ•จ์ˆ˜
    return () => clearTimeout(throttleTimer);
  }, [param]);

 

 

 

๋น„๊ต

debounce ๋ฐฉ์‹๊ณผ throttle ๋ฐฉ์‹์„ ๋น„๊ตํ•˜๊ธฐ ์œ„ํ•ด setTimeout ๋‚ด์— console.log๋ฅผ ๋„ฃ์–ด ์–ด๋–ป๊ฒŒ ์‹คํ–‰๋˜๋Š”์ง€ ํ™•์ธํ•ด๋ดค๋‹ค.

 

debounce ๋ฐฉ์‹

 

 

throttle ๋ฐฉ์‹

 

 

 

 

 

์ฐธ๊ณ 
https://velog.io/@jiynn_12/Debounce-%EC%99%80-throttle-%EC%97%90-%EB%8C%80%ED%95%B4-%EC%95%8C%EC%95%84%EB%B3%B4%EA%B3%A0-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8%EC%97%90-%EC%A0%81%EC%9A%A9%ED%95%B4%EB%B3%B4%EC%9E%90
https://velog.io/@eungbi/JS-debounce-throttle-%EA%B5%AC%ED%98%84%ED%95%98%EA%B8%B0
https://pks2974.medium.com/throttle-%EC%99%80-debounce-%EA%B0%9C%EB%85%90-%EC%A0%95%EB%A6%AC%ED%95%98%EA%B8%B0-2335a9c426ff

 

'react' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

React / Next.js  (2) 2025.04.29
React / ๋ฒˆ๋“ค๋ง, ์ฝ”๋“œ์Šคํ”Œ๋ฆฌํŒ…  (0) 2025.04.24
React / lazy, Suspense  (1) 2025.04.24
React / React Developer Tools  (0) 2025.04.24
React / ์ตœ์ ํ™” ํ•จ์ˆ˜  (0) 2025.04.23