[CS] 검색 최적화

Logun·2023년 8월 16일
0

CS

목록 보기
1/17
post-thumbnail

✅ 검색을 최적화 해야하는 이유

"나는 서울에사는 로건이다"라는 단어를 예시로 들어보자. "서울"이라는 단어(토큰)를 전체적으로 검색 하면 모든 값을 검색해야하는데, Disk i/o가 생겨 이 접근 방식은 시간이 걸리는 편이다.


✅ 해결 방안

  • 백엔드 최적화
    단어별로 쪼개 놓아서 따로 테이블과 위치를 저장해 놓는 것으로 해결을 하게 된다.

    ✌️ 역인덱스 (inverted-index) 방식
    ✌️ 토크나이징 (토큰화 하는것 - 단어 쪼개기)

이 과정을 쉽게 해주는 것으로 엘라스틱서치가 있고, 여기서 한 번 이라도 가져온 값은 Redis에서 캐싱하여 더욱 빠르게 접근하게 도와준다.

Redis에 없으면, 엘라스틱서치로, 엘라스틱서치에 없으면 DB로 직접 찾아가는 방식으로 데이터를 가져오게 된다.

  • 프론트엔드 최적화

    ✌️ 디바운싱 (Debouncing)
    => 특정 시간이내, 추가 입력 없을 시, 마지막 1회만 실행

    ✌️ 쓰로틀링 (Throttling)
    => 특정 시간이내, 추가 입력 있어도, 1회만 실행

    (모두 setTimeout으로 구현할 수 있음)

디바운싱(Debouncing)은 검색을 할 때 자동으로 결과값이 나오도록 하는 방식에 많이 사용하게 되었다. onChange 이벤트로 검색이 입력될 때마다 결과값을 가져오게 하였는데, 많은 요청이 들어오게 되어 문제가 되었다.

  • 디바운싱 (Debouncing)
     import _ from "lodash";
    
      const getDebounce = _.debounce((value) => {
        void refetch({ search: value, page: 1 });
        setKeyword(value);
      }, 500);
    
      const onChangeSearch = (event: ChangeEvent<HTMLInputElement>): void => {event.currentTarget.value, page: 1 });
        getDebounce(event.currentTarget.value);
      };

위의 방식으로 검색을 하게 되면 onChangeSearch를 지나 getDebounce로 값을 보내게 되고, 이 곳에서 마지막 입력 후 500 => 0.5초가 지난 후에 검색의 결과 값이 나오게 된다.

쓰로틀링(Throttling)은 스크롤 이벤트 시에 많이 사용하게 된다. 특정 시간내에 요청한 이벤트 중 마지막 것을 반영해주어 수많은 스크롤 이벤트를 막아준다.

  • 쓰로틀링(Throttling)
const handleScroll = (event: UIEvent<HTMLElement>) => {
  const { scrollTop, clientHeight, scrollHeight } = event.currentTarget;

  if (clientHeight + scrollTop >= scrollHeight) onLoadMore();
  
};

const onLoadMore = _.throttle(() => {
    if (data === undefined) return;
    void fetchMore({
      variables: {
        page: Math.ceil(data?.fetchUseditems.length ?? 10 / 10) + 1,
      },
      updateQuery: (prev, { fetchMoreResult }) => {
        if (fetchMoreResult.fetchUseditems === undefined)
          return { fetchUseditems: [...prev.fetchUseditems] };

        return {
          fetchUseditems: [
            ...prev.fetchUseditems,
            ...fetchMoreResult.fetchUseditems,
          ],
        };
      },
    });
  }, 1000);

위 코드는 무한스크롤을 할 때 사용하였는데, 스크롤을 내릴 때 수 많은 onScroll이벤트가 발생하게 된다. throttle을 적용해 주면, 해당 시간인 1000=>1초안에서 발생한 마지막 이벤트의 값이 나오게 된다.

profile
로건의 개발이야기

0개의 댓글