2 min read
React Query Offline-First 전략
네트워크 불안정 환경에서 캐시 우선 UX를 구현하기 위한 staleTime, persistence, sync 패턴

도입
모바일 네트워크가 불안정한 환경에서는 데이터 조회 실패가 곧바로 이탈로 이어진다. React Query를 기본 설정으로만 쓰면 로딩 스피너를 반복 노출하게 되고, 사용자는 동일 화면에서 상태가 튀는 경험을 하게 된다. 이 글은 캐시 우선 렌더링, 오프라인 큐, 온라인 복구 시점 동기화를 결합해 서비스 체감 품질을 높이는 실전 패턴을 정리한다.

문제 정의
오프라인 우선 전략이 실패하는 이유는 대부분 라이브러리 설정값이 아니라 제품 정책이 빠져 있기 때문이다. 다음 세 가지가 흔한 실패 조건이다.
- 동일 Query Key에 사용자 컨텍스트를 포함하지 않아 계정 전환 시 캐시가 섞인다.
- mutation 재시도 정책이 화면 흐름과 분리되어, 사용자는 성공처럼 보이지만 서버 반영은 실패한다.
- staleTime과 gcTime을 일괄 적용해 트래픽 패턴별 최적화가 불가능하다.
핵심은 네트워크 상태를 UX 상태와 동일하게 취급하지 않는 것이다. 오프라인이어도 읽기는 허용하고, 쓰기만 큐에 넣는 식으로 기능별 정책을 분리해야 한다.
핵심 개념
| 관점 | 설계 기준 | 검증 포인트 |
|---|---|---|
| 조회 정책 | 캐시 우선 + 백그라운드 재검증 | 첫 화면 렌더 시 API 호출 차단 여부 |
| 쓰기 정책 | 오프라인 큐 + 서버 idempotency | 재전송 중복 반영 여부 |
| 복구 정책 | online 이벤트 시 순차 flush | 복구 직후 데이터 충돌률 |
| 관측 지표 | cache hit rate + retry success | 세션당 실패 체감 횟수 |
오프라인 전략은 프론트엔드만의 문제가 아니다. 백엔드가 idempotency-key를 지원하지 않으면 큐 전략은 장기적으로 데이터 오염을 만든다. 따라서 API 계약과 함께 설계해야 한다.
코드 예시 1: QueryClient 기본 정책 분리
import { QueryClient } from "@tanstack/react-query";
export const queryClient = new QueryClient({
defaultOptions: {
queries: {
staleTime: 30_000,
gcTime: 10 * 60_000,
retry: 1,
refetchOnWindowFocus: false,
networkMode: "offlineFirst",
},
mutations: {
retry: 3,
networkMode: "offlineFirst",
},
},
});
export const key = {
feed: (userId: string) => ["feed", userId],
};
코드 예시 2: 오프라인 큐 flush
type PendingWrite = { id: string; endpoint: string; body: unknown; key: string };
const queue: PendingWrite[] = [];
export async function flushPendingWrites() {
for (const item of queue) {
const response = await fetch(item.endpoint, {
method: "POST",
headers: {
"Content-Type": "application/json",
"Idempotency-Key": item.key,
},
body: JSON.stringify(item.body),
});
if (!response.ok) break;
}
}
window.addEventListener("online", () => {
void flushPendingWrites();
});
아키텍처 흐름
Mermaid diagram rendering...
트레이드오프
- staleTime을 길게 잡으면 API 호출은 줄지만 데이터 신선도 관리 책임이 UI로 이동한다.
- offline queue를 넣으면 UX는 좋아지지만 서버 idempotency를 반드시 맞춰야 한다.
- 재시도 횟수를 높이면 성공률은 오르지만, 실패 원인 진단 로그가 없으면 장애 대응이 느려진다.
정리
React Query Offline-First의 핵심은 옵션 최적화가 아니라 운영 계약이다. 조회/쓰기/복구를 분리하고, API와 함께 재시도 규칙을 명시하면 네트워크 품질이 낮은 환경에서도 안정적인 사용자 경험을 유지할 수 있다.
이미지 출처
- Cover: source link
- License: CC BY-SA 3.0 / Author: Dave Gandy
- Note: Wikimedia Commons 무료 라이선스 이미지를 다운로드 후 1600px 기준 JPG로 최적화했습니다.