본문 바로가기
개발/React

리액트 - debounce vs throttle로 최적화하기 with useMemo (lodash-es)

by 피로물든딸기 2024. 4. 6.
반응형

리액트 전체 링크

 

참고

- https://www.npmjs.com/package/lodash-es

- React.memo, useMemo, useCallback으로 최적화하기

- Socket.IO로 Toast UI Editor 동시 편집하기

 

debouncethrottle은 성능 최적화를 할 때 사용된다.

debounce는 연속된 이벤트를 하나로 묶어 처리할 수 있다. (딜레이 적용)

throttle은 일정 시간 간격으로 이벤트를 호출되도록 제한한다. (주기적 호출)


debounce

 

예를 들어 input에서 타이핑을 할 때, 타이핑을 멈춘 후, 검색 요청을 보내고 싶다고 가정하자.

이런 경우 debounce를 이용할 수 있다.

 

예시 코드는 다음과 같다.

import React, { useMemo, useState } from "react";
import { debounce } from "lodash-es";

const DebouncedInput = () => {
  const [value1, setValue1] = useState("");
  const [value2, setValue2] = useState("");
  const [value3, setValue3] = useState("");

  const debounceChange = debounce((input) => {
    console.log(input);
  }, 500); // ms

  const debounceMemoChange = useMemo(() =>
    debounce((input) => { console.log(input); }, 500)
  , []);
  
  const handleChange1 = (e) => {
    let input = e.target.value;
    setValue1(input);
    console.log(input)
  };

  const handleChange2 = (e) => {
    let input = e.target.value;
    setValue2(input);
    debounceChange(input);    
  };

  const handleChange3 = (e) => {
    let input = e.target.value;
    setValue3(input);
    debounceMemoChange(input);    
  };

  return (
    <div style={{ margin: 5, display: "flex", flexDirection: "column", width: 200 }}>
      <input
        type="text"
        value={value1}
        onChange={handleChange1}
        placeholder="normal"
      />
      <input
        type="text"
        value={value2}
        onChange={handleChange2}
        placeholder="debounce"
      />
      <input
        type="text"
        value={value3}
        onChange={handleChange3}
        placeholder="useMemo + debounce"
      />
    </div>
  );
};

export default DebouncedInput;

 

debounce가 적용된 input은 설정한 시간(1000ms) 후에 이벤트가 한 번에 발생하는 것을 알 수 있다.

그리고 useMemo와 함께 적용하면 마지막 이벤트만 호출되도록 할 수 있다.


throttle

 

throttle스크롤과 같은 이벤트에 적용할 수 있다.

매 스크롤마다 이벤트가 발생해야 한다면 과부하가 걸리기 때문에, throttle일정 시간 간격에만 이벤트를 호출한다.

 

예시 코드는 다음과 같다.

import React, { useState, useEffect } from "react";
import { throttle } from "lodash-es";

const ThrottledScrollComponent = () => {
  const [scrollPosition, setScrollPosition] = useState(0);

  useEffect(() => {
    const throttledScrollHandler = throttle(() => {
      setScrollPosition(window.scrollY);
      console.log(window.scrollY);
    }, 2000); // ms

    window.addEventListener("scroll", throttledScrollHandler);

    return () => {
      window.removeEventListener("scroll", throttledScrollHandler);
    };
  }, []);

  return (
    <div>
      <h2>Scroll Position: {scrollPosition}</h2>
      <div style={{ height: "5000px", background: "#eee" }}>
        {/* long contents */}
      </div>
    </div>
  );
};

export default ThrottledScrollComponent;

 

throttle 적용으로 스크롤 이벤트가 발생하더라도 나설정한 시간 뒤에 갱신(2000ms)되는 것을 알 수 있다.

반응형

댓글