pile·
프론트엔드·더핑크퐁컴퍼니더핑크퐁컴퍼니·

Next.js App Router에서 prefetchQuery와 Suspense로 뚜루루뚜루 데이터 스트리밍하기

더핑크퐁컴퍼니가 Next.js App Router 마이그레이션 과정에서 React Query v5.40.0의 새로운 prefetchQuery 동작과 Suspense를 결합해 데이터 스트리밍을 구현한 경험을 다룬다. await 없이 prefetch를 실행하는 방식으로 FCP를 1.0s에서 0.5s로 줄이고 Lighthouse 성능 점수를 91점에서 98점으로 끌어올렸다.

핵심 포인트
  • React Query v5.40.0부터 prefetchQuery를 await 없이 실행해도 pending 상태 쿼리가 dehydrated state에 포함되어 클라이언트로 전달된다.
  • Waterfall(순차), Parallel(병렬), No-Await(스트리밍) 세 가지 데이터 로딩 전략을 비교했다.
  • No-Await 전략을 쓰면 서버가 첫 HTML을 즉시 스트리밍하고, 나머지 데이터는 Suspense가 클라이언트에서 채운다.
  • Pages Router 시절의 선택적 prefetch 패턴을 App Router에서 재구성하는 과정에서 발견한 접근이다.
  • 실제 결과: FCP 1.0s에서 0.5s로 단축, Lighthouse 성능 점수 91점에서 98점으로 향상했다.
상세 정리
  • 배경: Pages Router 시절 선택적 prefetch 전략을 쓰다가 Next.js 15 App Router로 마이그레이션을 시도했다.
  • Waterfall 문제: 서버 컴포넌트에서 쿼리를 await로 순차 실행하면 각 데이터 fetch가 완료될 때까지 렌더링이 블로킹된다.
  • Parallel 시도: 여러 쿼리를 병렬 실행했지만 모든 데이터가 준비될 때까지 응답이 지연됐다.
  • No-Await 전략: prefetchQuery를 await 없이 실행해 서버가 HTML을 즉시 내려보내고, 펜딩 상태 쿼리 정보만 클라이언트로 전달하는 방식이다.
  • v5.40.0 핵심 변화: await 없이 실행한 prefetch도 dehydrated state에 정상 포함되어 클라이언트 Suspense가 이어받을 수 있게 됐다.
  • Suspense 역할: 클라이언트는 dehydrated state를 받아 pending 쿼리를 Suspense로 감싸고, 데이터 도착 시 점진적으로 UI를 채운다.
  • 결과 수치: FCP 1.0s에서 0.5s로 단축, Lighthouse 성능 점수 91점에서 98점으로 향상했다.
  • 주의점: 모든 쿼리에 No-Await를 적용하면 서버 사이드에서 빈 상태가 먼저 노출될 수 있어, 초기 화면에 반드시 필요한 데이터는 await를 유지해야 한다.
왜 읽나Next.js App Router와 React Query를 함께 쓰면서 FCP를 줄이고 Suspense 기반 스트리밍을 도입하려는 프론트엔드 개발자에게 실전 비교와 수치 근거를 제공한다.
더핑크퐁컴퍼니
더핑크퐁컴퍼니 블로그
원문은 여기서 이어서 읽을 수 있어요
원문 읽기
읽음 (0)

이 글과 비슷한

  1. 프론트엔드·여기어때 (GC컴퍼니)여기어때 (GC컴퍼니)·

    항공 프론트엔드 구축기 (7/10): 창구를 하나만 두었습니다

    여기어때 항공 서비스 프론트엔드가 웹과 앱 웹뷰 두 환경에서 동일한 함수 호출로 동작하는 앱 브릿지 추상화 레이어를 설계한 과정을 다룬다. iOS·안드로이드 규약 차이와 "웹에 존재하지 않는 브릿지를 어떻게 호출하나"라는 문제를 단일 추상화 층으로 해결한 구현 사례다.

    요약 이어보기
    #react#typescript#webview+2