자바스크립트 - React.js

[ReactQuery] useSuspenseQuery를 사용해서 Suspense 성능 개선 및 최적화를 해보자 !

Lv1_junior_dev 2023. 12. 16. 23:15

❗️서론

최근 프로젝트를 진행하며 react-query의 Suspense를 적용하는 과정에서

그림에서 보는 것 처럼 데이터가 폭포(Waterfall)처럼 순차적으로 호출이 되어 로딩 화면이 장시간 노출되어버리는 골머리를 앓고있었다.

 

그러던 중에 링크드인의 일촌분께서 해당 방법을 해결할 수 있는 방법을 공유해주셔서 드디어 해결을 하였다 ...

https://tech.kakaopay.com/post/react-router-dom-csr-prefetch/

 

CSR 환경에서 Suspense로 발생한 문제 해결하고 성능 개선하기 | 카카오페이 기술 블로그

react-router-dom 기반의 CSR 환경에서 Suspense를 사용하면서 발생한 순차적 API호출 문제를 프리패칭을 통해 개선한 경험을 공유합니다.

tech.kakaopay.com

내가 참고하였던 포스팅이다 ! 

 

사실 구글링해도 다른 포스팅들도 많지만 내가 하는 코드에는 뭔가 제대로 적용이 되지 않았었어서

다음 기능 개발을 위해 우선 순위를 좀 미뤄두고 나중에 해야지.... 하였었는데 드디어 해결이 되어서 너무 속이 시원하다.

 

추가적으로 참고한 링크도 첨부 해두겠다.

https://suspensive.org/docs/react-query/useSuspenseQueries

 

useSuspenseQueries – Suspensive

Packages to use React Suspense easily

suspensive.org


❗️적용

본격적으로 내 프로젝트에서 적용한 부분에 대해서 다뤄보겠다.

export const useStockData = () => {
  const { data: stockData = [] } = useQuery<
    StockInformation[],
    AxiosError,
    StockInformation[],
    QueryKey
  >([QUERY_KEYS.STOCK_INFO], getStockInfo, {
    refetchInterval: 1000,
  });

  return { stockData };
};

export const useCommentList = (stockName: string) => {
  const { data: commentList } = useQuery<
    CommentData[],
    AxiosError,
    CommentData[],
    QueryKey
  >(
    [`${QUERY_KEYS.GET_COMMENT_LIST}/${stockName}`],
    () => getCommentList(stockName),
    {
      staleTime: 0,
      cacheTime: 10 * 60 * 1000,
    }
  );

  return commentList;
};

 

useSuspenseQuery 적용 이전에는 따로 구현해둔댓글 정보를 불러오는 query와 주식 정보를 들고오는 query를 각각 호출을 하여 호출 완료까지 1초라는 시간동안 사용자에게 로딩 화면이 보여지는 문제점이 발생하였다.

사실 1초라는 시간이 따지고보면 그렇게 긴 시간은 아니지만 충분히 줄일 수 있을 것 같은 부분이라고 확신이 들어서인지 너무나도 거슬렸다.

export const useGetStockDetailInfos = (stockName: string) => {
  const [{ data: stockData }, { data: commentData }] = useSuspenseQueries({
    queries: [
      {
        queryKey: [QUERY_KEYS.STOCK_INFO],
        queryFn: () => getStockInfo(),
        refetchInterval: 1000,
      },
      {
        queryKey: [`${QUERY_KEYS.GET_COMMENT_LIST}/${stockName}`],
        queryFn: () => getCommentList(stockName),
      },
    ],
  });

  const [, setRecoilStockData] = useRecoilState(stockDataState);

  useEffect(() => {
    setRecoilStockData(stockData);
  }, [stockData, setRecoilStockData]);

  return { stockData, commentData };
};

 

useSuspenseQuery를 적용한 코드는 다음과 같다.

 

useSuspenseQuery을 적용하여 2개의 쿼리를 queries 인자에 배열 형태로 전달하여서 사용하게끔 하였다.

이렇게 하여 데이터를 병렬로 호출하니 0.5~0.6초만에 데이터를 성공적으로 호출하여 이전보다 짧은 시간내에 

사용자에게 호출한 데이터를 보여줄 수 있게 되었다.

 

useSuspenseQuery를 사용하는 이유는 간단하다. 여러 쿼리를 병렬로 수행할 수 있도록 하기위해서이다 !! 

사실 이미 눈치챈 독자들도 있겠지만 useSuspenseQuery는 v5 부터  useQuries에서 이름이 바뀐것이다.

 

이번 포스팅은 useSuspenseQuery을 어쩌다가 적용하였고 어떻게 적용했는지만 다루고

빠른 시일내에 조금 더 깊게 학습하여 더 자세한 내용을 포스팅 해보겠다.

파이팅 !