[React] 검색 기능 성능 최적화하기

힛짱·2022년 12월 26일
1

React

목록 보기
2/6
post-thumbnail

🌟 최적화가 필요한 이유


프로젝트의 검색 기능 구현 중, 키워드를 입력할 때 마다 해당하는 많은 양의 데이터를 바로 목록에 뜨게 하려니 속도가 매우 느렸다. onChange이벤트나 스크롤 이벤트 등 한꺼번에 많은 이벤트를 처리해야할 경우 반드시 최적화가 필요하다.

검색할 때 키워드 목록을 보여주기 위해선 키워드를 입력할 때마다 API 요청을 해야 한다. "명수옹옹"을 검색하게 되면 총 4번의 API 요청을 해야하는데, 이는 매우 비효율적이다.


🤔 그렇다면 어떻게 최적화할까?


Debounce 를 사용하자!

Debounce 란?

  • 특정 이벤트가 발생할때 로직이 과도하게 발생하는 것을 방지하기위해 사용되는 함수이다.
  • 마지막 이벤트가 호출된 이후, 일정시간이 지난 후에 해당 함수의 기능이 동작한다.
  • 검색한 키워드에 해당하는 정보를 보여주는 기능 구현에 주로 사용한다.

Debounce 구현

일정 시간 후 코드를 비동기적으로 실행하는 함수인 setTimeout를 사용하여 디바운스를 구현해 보았다.

const Search = () => {
  const [user, setUser] = useState(false);
  const [keyword, setKeyword] = useState('');

  const searchUser = async (search) => {
      // API 요청 
      // ... 생략
  };
  
  // 디바운스 구현
  let timer;
  const checkInp = (e) => {
    const search = e.target.value;
    if (timer) { // 200ms 전에 입력이 발생되면 이전 타이머 취소
      clearTimeout(timer);
    }
    timer = setTimeout(() => {
      if (search) {
        searchUser(search);
        setKeyword(search);
      } else {
        setUser('');
      }
    }, 200);
  };

  return (
    <Wrap>
      <HeaderBSU checkInp={checkInp} />
      {user ? (
        user.map((item) => <SearchUser props={item} keyword={keyword} />)
      ) : (
        <SearchCont>
          <img src={searchMain} alt="" />
          <SearchMsg>유저를 검색해 팔로우 해보세요!</SearchMsg>
        </SearchCont>
      )}
      <NavBar />
    </Wrap>
  );
};

200ms 안에 연속으로 들어온 이전 요청들은 clearTimeout(timer) 으로 clear되고 마지막 요청만 실행한다.

즉, 키워드를 검색하게 되면 일정 시간(200ms)이 지난 후 마지막 호출에서 검색 키워드에 대한 API를 요청하게 되므로 더 효율적으로 성능을 최적화할 수 있다.


👻 유사하지만 다른 Throttle


Throttle 란?

  • 이벤트를 일정 주기마다 한 번 발생하도록 하는 함수이다.
  • 마지막 함수가 호출된 후 일정 시간이 지나기 전에 다시 호출되지 않도록 한다.
  • 무한 스크롤 기능 구현에 주로 사용한다.

Debounce 와 Throttle 차이점

디바운싱과 쓰로틀링은 성능을 목적으로 자바스크립트의 이벤트를 제어하기 위해 사용되는 기법이지만,
쓰로틀링은 X 밀리 초마다 정기적으로 기능 실행을 보장한다는 것이다.
디바운싱은 아무리 많은 이벤트가 발생해도 특정 시간 사이에 어떤 이벤트도 발생하지 않았을 때 딱 한번만 마지막 이벤트를 발생시킨다.


참고 : Debounce 와 Throttle 차이점

profile
프론트엔드 개발자 장희수입니다😉

0개의 댓글