들어가며
어떤 페이지에 접근했을때, 화면 구성요소가 로딩되는데 너무 오래걸려 답답했던적이 있으신가요? 화면 로딩을 오래걸리게 만드는 원인에는 서비스의 구현과 유저의 환경에 따라 천차만별이지만, 유저의 이탈을 방지하기 위해 꼭 신경써야 할 부분 중 하나입니다.
이번 포스트에서는 prefetch를 이용해 tanstack query를 이용하는 서비스에서 네트워크 응답시간을 줄이는 방법을 알아보도록 하겠습니다. 글에서 사용된 코드 라이브러리 버전은 v4를 기준으로 하겠습니다.
Prefetch 란?
prefetch는 이름처럼 필요한 데이터를 미리 fetch하는 기법입니다. 어떠한 페이지에 진입했을때 UI를 구성하기 위해 네트워크 요청을 보내야 한다고 하면, 이때 필요한 데이터를 기존의 요청 시점보다 조금 빨리 요청해서 UI 표시까지 걸리는 시간을 단축하는 원리입니다.
데이터를 요청하는 시점을 앞으로 당기는 방법은 여러가지가 있습니다. 기본적으로 유저가 해당 데이터를 필요로 할 것이 확실하거나 유력한 상황이 왔을때 페칭을 시작하면 되는데, 다음과 같은 조건들을 생각해 볼 수 있습니다.
- 해당 페이지로 향하는 버튼에 마우스를 올리거나(Hover) 혹은 눌렀을때
- 퍼널 분석을 통해 사용자가 이전에 해당 데이터를 많이 요청했던 경로에 진입했을때
- 단순히 시간이 남을때 (idle)
다만 퍼널 분석의 경우 유저가 일정 기간 이상 축적한 데이터가 필요하고, 단순히 시간이 남는다고 데이터를 페칭 해오는건 불필요한 자원 낭비가 될 수 있습니다. 서비스가 가진 성격에 따라 어떤 페칭 방법을 적용하는 것이 베스트일지는 매번 달라지기 때문에, 서비스와 자원의 유형에 따른 고찰이 필요합니다.
개인적으로는 위의 세 가지 방법 중 첫 번째 방법을 많이 사용해서, 예시 코드를 보겠습니다.
Prefetch 예시
글 목록 역할을 하는 "페이지 A" 에서 글 상세의 역할을 하는 "페이지 B"로 이동하는 버튼을 클릭한 경우를 보겠습니다.
/**
* 페이지 B (글 상세)로 넘어가는 버튼 핸들러 함수
*/
const handlePrefetchAndNavigate = async (postId: string) => {
await queryClient.prefetchQuery({
/** 글 상세정보를 가져오는 쿼리키와 쿼리 함수 */
queryKey: postKeys.postInfo(postId),
queryFn: getPostInfo(postId),
});
navigate(`/post/${postId}`);
};
// ...
return (
<div>
{/** 클릭시 navigate와 동시에 prefetch 시작 */}
<button onClick={handlePrefetchAndNavigate} />
</div>
);
이렇게 되면 버튼을 클릭하는 동시에 요청을 시작하고, 페이지에 도착해서는 이미 받아온, 혹은 받아오고 있는 데이터를 사용하게 되어 로딩 시간이 줄어들게 됩니다.
/**
* 페이지 B (글 상세) 에서 기존에 사용하던 쿼리
* 새로 요청을 보내지 않고, 핸들러 함수에서 보냈던 요청의 응답을 그대로 사용한다.
*/
const { data: postData, isLoading } = useQuery({
queryKey: postKeys.postInfo(postId),
queryFn: getPostInfo(postId),
});
// ...
return (
<div>
<div>{postData.title}</div>
<div>{postData.author}</div>
{/** ... */}
</div>
);
추가로 스토어에 캐싱된 응답이 존재한다면 prefetch를 하지 않도록 조건을 걸어주는 등 prefetch에 대한 최적화 작업도 가능합니다.
const handlePrefetchAndNavigate = async (postId: string) => {
const isExist = queryClient.getQueryData(queryKeys.postInfo(postId));
if (!isExist) {
await queryClient.prefetchQuery({
queryKey: postKeys.postInfo(postId),
queryFn: getPostInfo(postId),
});
}
// ...
}
맺으며
빠르게 화면을 띄워주는건 프론트엔드 개발자들에겐 항상 고민인 부분인데, 이를 위한 다양한 방법들 중 prefetch는 네트워크 요청 완료 시간을 앞당겨 해결하는 방법입니다. 간단한 코드 몇 줄 만으로도 효과를 볼 수 있어 쉽게 적용할 수 있다는 장점이 있어 저도 많이 사용하고 있네요.
이와 비슷하게, 불러와야 할 코드의 양을 줄이는 지연 로딩 같은 방법도 prefetch와 함께 사용하기 좋습니다. 다음에는 지연 로딩을 통해 어떻게 페이지 로드 시간을 줄일 수 있는지 소개해보는것도 좋겠네요.
읽어주셔서 감사드리고, 틀린 내용에 대한 지적은 언제든 환영합니다.
'이론 > Frontend' 카테고리의 다른 글
TanStack-Query 효율적으로 활용하기 (0) | 2025.03.04 |
---|---|
타입 안정성을 위한 as unknown as Type (1) | 2024.10.21 |
Impression log 사용하기 (1) | 2024.07.01 |
React 19? 18.3 먼저 살펴보기 (0) | 2024.05.05 |
classname으로 스타일 간결하게 관리하기 (0) | 2024.03.24 |
댓글