Skip to content

refactor: 페이지 전환 논블로킹 전환 (pending 쿼리 스트리밍) - #360

Merged
ychany merged 15 commits into
devfrom
refactor/359-page-transition
Jul 24, 2026
Merged

refactor: 페이지 전환 논블로킹 전환 (pending 쿼리 스트리밍)#360
ychany merged 15 commits into
devfrom
refactor/359-page-transition

Conversation

@ychany

@ychany ychany commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

작업 요약

  • RSC 의 블로킹 prefetch 를 pending 쿼리 스트리밍으로 전환해 페이지 전환 지연을 제거합니다
  • 홈·마이·알림 등 6개 페이지의 await 를 제거하고 레이아웃과 중복된 fetch 2건을 정리합니다
  • 탭 전환 애니메이션 동안 목적지 라우트를 프리페치해 로딩을 병렬화합니다
  • 유저 정보 staleTime 을 5분으로 상향합니다

작업 세부 내용

배경

페이지 전환 시 RSC 가 await prefetchQuery() 로 백엔드 응답을 다 기다린 후에야 화면을 내려줘서, 클라 캐시가 fresh 해도 매 전환마다 서버 왕복만큼 이전 화면에 멈추는 문제. 전수조사 결과는 page-transition-refactoring.md 참고.

1. 스트리밍 전제 설정

  • queryClientdehydrate.shouldDehydrateQuery 에 pending 포함 — RSC 가 fetch 완료를 기다리지 않고 진행 중인 promise 를 스트리밍 (TanStack Query v5 공식 패턴)

2. await 제거 (6곳)

  • notification · tournament/[id]/result/group (자체 isPending/isError 폴백 완비)
  • mypage · mypage/edit · tournament/join/[id] (useSuspenseQuery 소비)
  • home/_components/tournament-list — page.tsx 가 아닌 자식 RSC 의 숨은 블로킹이라 전수조사에서 추가 발견

3. 레이아웃과 중복된 fetch 제거 (2곳)

  • tournament/[id]/create: ['tournament'] prefetch 삭제 — 상위 layout 이 이미 조회·시드
  • mypage/withdraw: 페이지 측 getMe() 삭제 — layout 과 이중 블로킹이었음. 닉네임 문구는 WithdrawGreeting 클라 컴포넌트가 layout 이 시드한 캐시를 읽음 (추가 요청 없음)

4. 탭바 프리페치

  • 탭 전환이 "착지 애니메이션(480ms) 후 router.push" 구조라, 애니메이션 동안 목적지 라우트를 router.prefetch (탭·드래그 스냅 양쪽) → push 시점엔 페이로드 도착 완료

5. staleTime

  • ['me'] 60초 → 5분 (유저 정보는 거의 안 변함 — 즉시 전환 유효 범위 확대)

체감 변화

시나리오 이전 이후
재방문/탭 전환 (캐시 fresh) 서버 왕복만큼 멈춤 즉시 렌더
첫 방문 이전 화면 유지 후 전환 동일 (악화 없음 — 스켈레톤 신설은 스코프 제외)

변경하지 않은 것 (의도)

  • match · result · login 페이지, 레이아웃 3종(tournament/[id] · archive · withdraw) — 데이터 기반 redirect/권한 가드 의존이라 await 유지
  • 아카이브 탭 진입 시 layout 의 getMe 왕복 1회는 남음 (권한 가드 비용 — 개선하려면 가드 재설계 별도 논의 필요)

검증

  • tsc · eslint · 프로덕션 빌드 통과
  • dev 배포 후: 홈 ↔ 마이 왕복 시 2회째 즉시 렌더
  • 첫 방문(시크릿) 현행과 동일 동작 (악화 없음)
  • mutation → invalidate 회귀 (프로필 수정, 알림 읽음 처리)
  • 앱 웹뷰 동일 시나리오

연관 이슈

closes #359

Summary by CodeRabbit

  • 새로운 기능
    • 회원 탈퇴 안내 화면에 사용자 닉네임을 반영한 맞춤 문구를 추가했습니다.
  • 개선 사항
    • 홈/마이페이지/알림/대회(참가·생성·결과) 페이지의 데이터 프리패치가 비차단 방식으로 개선되어 초기 표시와 전환 반응성이 향상되었습니다.
    • 사용자(“me”) 데이터 캐시 유지 시간을 늘려 재방문 시 더 빠르게 로드됩니다.
    • 하단 탭 전환이 포인터 제스처에 맞춰 더 즉시 동작하며, 탭바 표시 위치가 레이아웃 기준으로 정리되었습니다.
  • 문서
    • 페이지 전환 지연 개선 가이드를 추가했습니다.

@vercel

vercel Bot commented Jul 19, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
piki Ready Ready Preview, Comment Jul 24, 2026 2:14pm

@github-actions github-actions Bot added the refactor Extra attention is needed label Jul 19, 2026
@github-actions
github-actions Bot requested review from iOdiO89 and kanghaeun July 19, 2026 17:01
@github-actions

Copy link
Copy Markdown

Discord 스레드 연동용 메타데이터입니다. discord-pr-bot 워크플로가 자동 생성하며, 수정·삭제하면 PR 과 Discord 알림 연동이 끊깁니다.

@coderabbitai

coderabbitai Bot commented Jul 19, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@ychany, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 52 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 42e8dc78-2ebd-4b24-b339-c167daff1520

📥 Commits

Reviewing files that changed from the base of the PR and between c39df59 and 2415b86.

📒 Files selected for processing (1)
  • apps/web/src/components/bottom-tab-bar/index.tsx
📝 Walkthrough

Walkthrough

React Query가 pending 쿼리를 dehydration하도록 설정되었고, 여러 페이지의 prefetch 대기가 제거되었습니다. 탈퇴 안내 조회를 클라이언트로 이동했으며, BottomTabBar를 전역 레이아웃에 배치하고 탭 라우팅을 즉시 처리하도록 변경했습니다.

Changes

페이지 전환 스트리밍

Layer / File(s) Summary
Pending dehydration 계약
apps/web/src/utils/queryClient.ts, apps/web/src/hooks/useGetMe.ts, docs/page-transition-refactoring.md
pending 쿼리를 dehydration 대상에 포함하고 me 쿼리의 staleTime을 5분으로 설정했으며 관련 절차와 검증 항목을 문서화했습니다.
페이지 prefetch 비대기 처리
apps/web/src/app/home/..., apps/web/src/app/mypage/..., apps/web/src/app/notification/page.tsx, apps/web/src/app/tournament/...
여러 페이지에서 prefetch 완료 대기를 제거하고 생성 페이지의 중복 tournament prefetch를 삭제했습니다.
탈퇴 페이지 사용자 조회 분리
apps/web/src/app/mypage/withdraw/...
페이지의 서버 getMe 호출을 제거하고 닉네임 안내를 클라이언트 컴포넌트로 이동했습니다.

전역 하단 탭 내비게이션

Layer / File(s) Summary
전역 탭바 배치
apps/web/src/app/layout.tsx, apps/web/src/app/home/page.tsx, apps/web/src/app/archive/...
BottomTabBar를 전역 레이아웃에서 렌더링하고 개별 화면의 중복 렌더링을 제거했습니다.
탭 prefetch 및 즉시 라우팅
apps/web/src/components/bottom-tab-bar/index.tsx
포인터 입력 시 대상 라우트를 prefetch하고 제스처 종료 시 router.push를 즉시 호출하도록 변경했습니다.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant BottomTabBar
  participant NextRouter
  participant ServerPage
  participant QueryClient

  User->>BottomTabBar: 탭 누르기
  BottomTabBar->>NextRouter: router.prefetch(href)
  User->>BottomTabBar: 제스처 종료
  BottomTabBar->>NextRouter: router.push(href)
  NextRouter->>ServerPage: 페이지 전환
  ServerPage->>QueryClient: 비대기 prefetch 및 pending dehydrate
Loading

Possibly related PRs

Suggested labels: WEB

Suggested reviewers: iodio89, kanghaeun

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 제목이 pending 쿼리 스트리밍으로 페이지 전환을 비동기화하는 핵심 변경을 간결하게 잘 요약합니다.
Linked Issues check ✅ Passed pending dehydrate 설정, 대상 페이지 await 제거, 중복 fetch 정리, staleTime 조정이 모두 요구사항과 일치합니다.
Out of Scope Changes check ✅ Passed 추가된 BottomTabBar 이동과 문서 갱신도 페이지 전환 리팩토링 범위에 맞아 보이는 별도 범위 이탈은 없습니다.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactor/359-page-transition

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/page-transition-refactoring.md`:
- Around line 3-4: Update the 전수조사 반영 date in the document header to 2026-07-19,
keeping the 작성일 and 대상 metadata unchanged.
- Around line 43-46: Update the staleTime execution plan to reflect the
completed 5-minute override for me in useGetMe, distinguishing it from the
60-second default. Mark this item as verified rather than future tuning, and
remove the claim that there are zero individual staleTime overrides while
preserving the pending shouldDehydrateQuery work.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 6ff65db9-695a-4b54-8fc4-7cf22261a1a4

📥 Commits

Reviewing files that changed from the base of the PR and between 8a09a24 and 11b2695.

📒 Files selected for processing (13)
  • apps/web/src/app/home/_components/tournament-list/index.tsx
  • apps/web/src/app/mypage/edit/page.tsx
  • apps/web/src/app/mypage/page.tsx
  • apps/web/src/app/mypage/withdraw/_components/WithdrawGreeting.tsx
  • apps/web/src/app/mypage/withdraw/page.tsx
  • apps/web/src/app/notification/page.tsx
  • apps/web/src/app/tournament/[id]/create/page.tsx
  • apps/web/src/app/tournament/[id]/result/group/page.tsx
  • apps/web/src/app/tournament/join/[id]/page.tsx
  • apps/web/src/components/bottom-tab-bar/index.tsx
  • apps/web/src/hooks/useGetMe.ts
  • apps/web/src/utils/queryClient.ts
  • docs/page-transition-refactoring.md

Comment thread docs/page-transition-refactoring.md
Comment thread docs/page-transition-refactoring.md Outdated
@kanghaeun kanghaeun changed the title PR 제목: refactor: 페이지 전환 논블로킹 전환 (pending 쿼리 스트리밍) refactor: 페이지 전환 논블로킹 전환 (pending 쿼리 스트리밍) Jul 19, 2026
@iOdiO89
iOdiO89 marked this pull request as draft July 24, 2026 09:19
@iOdiO89
iOdiO89 marked this pull request as ready for review July 24, 2026 09:55
@gemini-code-assist

Copy link
Copy Markdown

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

@iOdiO89 iOdiO89 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

내용 내가 좀 정리하면서 하나 더 추가했어!

변경사항

  1. void queryClient.prefetch → queryClient.prefetch로 변경 (void 명시 삭제. 불필요)
  2. 일부 중복된 주석 삭제

추가사항

  1. BottomTab 클릭 시 페이지 전환 지연 발생 → layout으로 BottomTab 위치 옮겨 지연 삭제

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/web/src/app/home/_components/tournament-list/index.tsx`:
- Around line 19-22: Update the prefetchQuery configuration to use the same
queryKey shape as TournamentListClient, including the limit value of 3 alongside
TOURNAMENT_LIST_STATUS. Keep the queryFn request parameters aligned with that
prefetched list so hydration reuses the cache instead of issuing a duplicate
request.

In `@apps/web/src/components/bottom-tab-bar/index.tsx`:
- Around line 118-121: Update the prefetch logic around pressTabForPrefetch in
the bottom tab bar to also prefetch the drag snap destination represented by
TABS[targetIndex]. Ensure the route selected by handleUp is prefetched even when
dragging starts on the active tab and pressIndex equals activeIndex, while
preserving the existing click prefetch behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 1e8eb808-9989-4042-ad62-9b4668e84547

📥 Commits

Reviewing files that changed from the base of the PR and between 60d8c17 and c39df59.

📒 Files selected for processing (12)
  • apps/web/src/app/archive/tournament/page.tsx
  • apps/web/src/app/archive/wish/_components/WishlistBottomBar.tsx
  • apps/web/src/app/home/_components/tournament-list/index.tsx
  • apps/web/src/app/home/page.tsx
  • apps/web/src/app/layout.tsx
  • apps/web/src/app/mypage/edit/page.tsx
  • apps/web/src/app/mypage/page.tsx
  • apps/web/src/app/notification/page.tsx
  • apps/web/src/app/tournament/[id]/create/page.tsx
  • apps/web/src/app/tournament/[id]/result/group/page.tsx
  • apps/web/src/app/tournament/join/[id]/page.tsx
  • apps/web/src/components/bottom-tab-bar/index.tsx
🚧 Files skipped from review as they are similar to previous changes (4)
  • apps/web/src/app/tournament/join/[id]/page.tsx
  • apps/web/src/app/tournament/[id]/create/page.tsx
  • apps/web/src/app/mypage/page.tsx
  • apps/web/src/app/tournament/[id]/result/group/page.tsx

Comment thread apps/web/src/app/home/_components/tournament-list/index.tsx
Comment thread apps/web/src/components/bottom-tab-bar/index.tsx
@ychany
ychany merged commit 1890bff into dev Jul 24, 2026
7 checks passed
@ychany
ychany deleted the refactor/359-page-transition branch July 24, 2026 14:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

refactor Extra attention is needed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Perf/Web] 페이지 전환 속도 개선 — RSC 블로킹 prefetch 를 pending 스트리밍으로 전환

2 participants