Throttling & Debouncing

이재홍·2022년 6월 6일
0

React

목록 보기
16/25
post-thumbnail

디바운싱 & 쓰로틀링

간단한 검색 기능을 통해 디바운싱과 쓰로틀링에 대하여 알아보도록 했다.

검색어 입력하는 인풋과 검색하기 버튼을 만들고 검색어를 저장해야하니까 onChange 함수를 만들어 준다.

++검색어가 저장될 state도 만들어줌

const [search, setSearch] = useState("");
  const onChangeSearch = (event) => {
    setSearch(event.target.value); // 검색어
  };

검색하기 버튼을 눌렀을 때 실행되는 함수를 만듬. onClickSearch

버튼을 눌렀을 때 refetch 하는데 검색하기 눌렀을때의 variables는 search가 들어가야한다.

search는 스테이츠에 저장되어있는 값을 넣어준다.

++search 에 해당하는 글들의 1페이지 2페이지 3페이지 가 나올텐데 그것도 생각해봐야한다.

→ 그 검색결과에 몇페이지를 보여줄 것인지 page가 붙어야한다 (variables에), 일반적으로 1페이지가 나오는 것이 일반적인 생각이니까 1페이지를 넣어보자.

+search 도 fetch해주어야 하니 fetchBoard 수정.

한줄요약: 검색은 refetch 이다!

debouncing(디바운싱)

검색하기 버튼을 빼버리고 검색어 입력부분으로만 검색

원리 : 클릭해서 refetch 했던 것을 변경할때마다 refetch 하면 되는 것이다!

// const [search, setSearch] = useState("");
  const onChangeSearch = (event: ChangeEvent<HTMLInputElement>) => {
    // setSearch(event.target.value);
    refetch({ search: event.target.value, page: 1 });
  };

굳이 state에 저장해서 refetch 하는 것이 아닌 바로 event.target.value로 refetch 시켜버리는 것

→ 굉장히 심플해졌다.

근데 여기에는 한가지 문제가 있다. Network 쪽을 한번 보자.

  • 엄청나게 요청을 보내게 되어버린다! (백엔드에서는 부하가 감당이 안된다)
    • 글을 입력하고 1초정도 쉬었을때를 입력에 끝으로 보고 요청을 하게 된다면 지금처럼 부하가 가진 않을 것이다. → debouncing (디바운싱) 이라고 한다 , 특정시간을 기준으로 해당시간내에 요청된 내용들은 무시!

디바운싱을 하기 위해 Lodash 라는 라이브러리를 사용했다.
Lodash는 자바스크립트의 유틸리티 라이브러리이다.

내장되어 있는 유용한 함수가 많기 때문에 자주사용!

Lodash의 많은 기능 중 디바운싱 내용에 대해 알아보자!

먼저 Lodash를 사용하기 위해서는 설치를 해야 한다.

yarn add lodash
yarn add -D @types/lodash // 타입

이제 refetch를 할때마다 요청을 보내는것이 아닌 디바운싱을 하는 것이다.

// 사용법은 setTimeout이랑 비슷하다
  const getDebounce = _.debounce((mydata) => {
    refetch({ search: mydata, page: 1 });
    // 1초 딜레이 후에 실행되야 하는것은 refetch 이기 때문에 위치를 디바운싱 안으로 이동! (onChage에서)
  }, 1000);
  const onChangeSearch = (event: ChangeEvent<HTMLInputElement>) => {
    **getDebounce(event.target.value);**
    // 체인지 할때마다 디바운싱이 실행되는데 매번 실행되는 것이 아닌 1초 기다렸다가 실행이 되는 것.
    // event.target.value 의 위치도 조심, 디바운스 안에 있는 것이 아님.
  };

실제 실무에서는 1초는 너무 길어서 0.2초 단위로 넣어서 사용한다. 200

Throttling(쓰로틀링)

먼저 실행하고 특정시간동안 재실행안하고 기다리는 것! 디바운싱과 다른부분.

  • 디바운싱은 입력하고 기다리고 실행. (검색기능)

쓰로틀링이란, 연이어 발생한 이벤트에 대해 일정한 delay를 포함 시켜, 연속적으로 발생하는 이벤트는 무시하는 방식으로 사용됨

즉, 지정한 delay동안 호출된 함수는 무시, 쓰로틀링이 사용되는 대표적 예제는 스크롤 기능이 있습니다

스크롤 이벤트를 걸어두면 스크롤을 내릴때 엄청나게 많은 스크롤 이벤트가 요청된다. 그때 쓰는 것이 쓰로틀링.


단어 표시 Tip

검색어 입력에 들어간 단어를 빨간색으로 표시해주고 싶다 → 방법?

import { useQuery, gql } from "@apollo/client";
import styled from "@emotion/styled";

const FETCH_BOARDS = gql`
  query fetchBoards($page: Int) {
    fetchBoards(page: $page) {
      _id
      writer
      title
      contents
    }
  }
`;

const MyRow = styled.div`
  display: flex;
`;

const MyColumn = styled.div`
  width: 25%;
`;

export default function MapBoardPage() {
  const { data, refetch } = useQuery(FETCH_BOARDS);

  const onClickPage = (event) => {
    refetch({ page: Number(event.target.id) });
  };

  return (
    <div>
      {data?.fetchBoards.map((el: any) => (
        <MyRow key={el._id}>
          <MyColumn>{el.writer}</MyColumn>
          <MyColumn>{el.title}</MyColumn>
        </MyRow>
      ))}
      {new Array(10).fill(1).map((_, index) => (
        <span key={index + 1} id={String(index + 1)} onClick={onClickPage}>
          {index + 1}
        </span>
      ))}
    </div>
  );
}
const [keyword, setKeyword] = useState("");
{el.title
              .replaceAll(keyword, `#$%${keyword}#$%`)
              .split("#$%")
              .map((el) => (
                <Word key={uuidv4()} isMatched={keyword === el}>
                  {el}
                </Word>
              ))}
// 이모션
const Word = styled.span`
  color: ${(props: IProps) => (props.isMatched ? "red" : "black")};
`;

state와 타이틀 부분에 수정.

yarn add uuid , yarn add --dev @types/uuid

refetch 할때 setKeyword 에 저장하고 그것을 빨간색으로 바꿔준다.

철수를 기준으로 쪼개면 3덩어리로 쪼개지게 되는 것. (split)

그리고 map으로 꾸미게 되면 각각이 화면에 그려지고 그렬질때 keyword와 같다면 isMatched 가 true로 되는 것이다!

replaceALL = 키워드를 변경시켜줌. 변경시켜준 값을 기준으로 split으로 짤라버림.

이모션
const **Word** = styled.span`
  **color: ${(props: any) => (props.isMatched ? "red" : "black")};**
`;

0개의 댓글