리액트 프로젝트를 하다 보면,
“리스트에서 상세 페이지로 넘어갈 때 로딩이 살짝 걸리는” 그 순간이 늘 아쉽습니다.
데이터가 많지 않아도, 네트워크 요청이 새로 일어나니까
사용자는 매번 짧은 ‘멈춤’을 경험하게 됩니다.
저는 이 문제를 해결하기 위해 여러 가지 방법을 써봤는데,
그중 가장 확실하게 체감된 게 바로 React Query의 prefetch 기능이었습니다.
말 그대로 “사용자가 클릭하기 전에 데이터를 미리 가져오는” 기법이죠.
처음엔 단순히 캐시가 오래 남는 줄 알았다
React Query의 캐시를 익히면서 “데이터가 남아 있으니 괜찮겠지”라고 생각했습니다.
하지만 캐싱은 ‘한 번이라도 가져온 적이 있는’ 데이터에만 적용됩니다.
즉, 아직 들어가보지 않은 페이지의 데이터는 여전히 로딩이 필요합니다.
그걸 해결해주는 게 queryClient.prefetchQuery()입니다.
이건 실제로 해당 쿼리를 실행하지는 않지만,
미리 백그라운드에서 데이터를 요청하고 캐시에 저장해 둡니다.
그리고 사용자가 그 페이지에 들어오면
이미 캐시에 있는 데이터를 즉시 보여주는 식이죠.
코드로 보면 금방 감이 온다
아래는 리스트 항목을 클릭하면 상세 페이지로 이동하는 예시입니다.
import { useQueryClient } from '@tanstack/react-query';
import { Link } from 'react-router-dom';
import axios from 'axios';
function PostList({ posts }) {
const queryClient = useQueryClient();
const prefetchPost = (id) => {
queryClient.prefetchQuery({
queryKey: ['post', id],
queryFn: () => axios.get(`/api/posts/${id}`).then((res) => res.data),
staleTime: 1000 * 60 * 5, // 5분 동안 신선한 상태로 유지
});
};
return (
<ul>
{posts.map((post) => (
<li
key={post.id}
onMouseEnter={() => prefetchPost(post.id)}
onFocus={() => prefetchPost(post.id)}
>
<Link to={`/posts/${post.id}`}>{post.title}</Link>
</li>
))}
</ul>
);
}
핵심은 onMouseEnter입니다.
사용자가 마우스를 올려두는 순간, React Query가 백그라운드에서
해당 포스트의 데이터를 미리 가져옵니다.
그리고 실제로 클릭해서 들어갔을 때는
이미 캐시에 있기 때문에 로딩이 거의 없습니다.
짧은 네트워크 지연이 아예 사라지는 거죠.
이걸 적용했을 때 진짜 달라졌다
예전에 게시판 프로젝트를 만들 때,
게시물 목록에서 상세보기로 이동할 때마다 1초 정도의 로딩이 있었습니다.
그때 prefetch를 적용했더니
마치 SPA가 아니라 네이티브 앱처럼 화면이 바로 뜨더군요.
심지어 서버 요청 수도 줄었습니다.
왜냐면 사용자가 마우스를 올렸다가 클릭하지 않아도
React Query가 알아서 캐시를 관리하니까,
짧은 시간 내에 같은 요청이 중복되지 않습니다.
이전엔 “클릭 후 로딩 중”이 보이던 걸
이젠 “클릭 즉시 렌더링”으로 바꿔준 겁니다.
작은 변화지만, UX 체감은 완전히 다릅니다.
주의해야 할 부분
한 가지 주의할 건, prefetch를 남용하면
불필요한 네트워크 요청이 많아질 수 있다는 점입니다.
예를 들어 목록에 100개가 있는데,
사용자가 스크롤만 해도 100개의 prefetch가 일어나면 큰일이죠.
그래서 저는 보통 사용자 의도가 명확한 경우에만 prefetch를 트리거합니다.
- 마우스 오버
- 터치 후 0.5초 이상 유지
- “자세히 보기” 버튼 근처에서 대기 중
이런 시점이 적당합니다.
실무에서의 팁
prefetch는 특히 페이지 전환이 잦은 관리자 페이지나
상품 상세 보기, 유저 프로필 보기 같은 곳에서 효과가 큽니다.
한 프로젝트에서는
상품 목록 hover 시 prefetchQuery로 상세 데이터를 불러오고,
상세 페이지에선 캐시된 데이터만 즉시 렌더링했습니다.
API 호출 수가 줄고, UX도 자연스러워졌습니다.
심지어 “이제 로딩이 안 보여서 신기하다”는 피드백도 받았어요.
결국, 사용자의 ‘다음 행동’을 미리 준비하는 기술
prefetch는 단순한 최적화가 아닙니다.
사용자의 움직임을 예측해서,
‘다음 동작이 일어날 때 이미 준비되어 있는 상태’를 만드는 기술입니다.
React Query가 단순히 비동기 요청을 처리하는 도구를 넘어서
UX를 설계하는 도구로 쓰일 수 있다는 걸
이 기능을 통해 제대로 느꼈습니다.
다음 글에서는 React Query의 캐시와 prefetch를 함께 확장해서,
다중 페이지 데이터 동기화 — 한 곳에서 수정해도 모든 화면이 자동으로 반영되는 구조를 다뤄보겠습니다.
이건 실제로 협업 프로젝트에서 “데이터 일관성 문제”를 해결해준 핵심 포인트였습니다.