Skip to content

feat: 기사님 상세 리뷰 페이지네이션에 prefetch 적용 - #77

Merged
yooseohyeon merged 2 commits into
devfrom
perf/prefetch-mover-reviews
Aug 7, 2026
Merged

feat: 기사님 상세 리뷰 페이지네이션에 prefetch 적용#77
yooseohyeon merged 2 commits into
devfrom
perf/prefetch-mover-reviews

Conversation

@yooseohyeon

@yooseohyeon yooseohyeon commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

📋 작업 내용

  • 기사 상세 페이지의 리뷰 페이지네이션 전환 체감 속도를 개선하기 위해, 페이지 버튼 hover 시 다음 리뷰 데이터를 미리 조회하도록 적용했습니다.

🔥 변경 사항

  • MoverDetailReviews

    • TanStack Query prefetchQuery로 hover한 리뷰 페이지 데이터를 미리 캐시하도록 추가했습니다.
    • 기존 리뷰 목록 query key·API 함수를 동일하게 사용해 클릭 시 캐시 데이터를 재사용합니다.
  • Pagination

    • 선택적으로 사용할 수 있는 onPagePrefetch prop을 추가했습니다.
    • 페이지 번호 및 이전/다음 버튼에 포인터 진입 시 대상 페이지를 프리패치합니다.
    • 현재 페이지와 비활성화된 이전/다음 페이지는 프리패치하지 않습니다.

✅ 체크리스트

  • 로컬에서 정상 동작을 확인했습니다.
  • 기존 기능에 영향을 주지 않는지 확인했습니다.
  • 불필요한 console.log를 제거했습니다.
  • lint를 통과했습니다.
  • README 또는 문서를 수정했습니다. (필요 시)
  • API 명세와 일치하는지 확인했습니다.

💬 To Reviewer

  • 페이지 번호 또는 이전/다음 버튼 hover 시 해당 리뷰 페이지 API가 사전 요청되고, 클릭 시 TanStack Query 캐시를 재사용하는 흐름을 중점적으로 확인 부탁드립니다.
  • 상세 정보와 리뷰 첫 페이지를 동시에 prefetch, 기사님 찾기에서 기사님 카드에 상세 링크에 마우스를 올렸을 때 상세와 첫 리뷰를 클라이언트 캐시로 미리 채우기 등의 성능 개선은 필요할 경우 후속 작업으로 진행할 예정입니다.

Summary by CodeRabbit

  • 새로운 기능
    • 리뷰 목록에서 다음 페이지 데이터를 미리 불러와 페이지 이동 시 더 빠르고 원활하게 표시합니다.
    • 페이지 버튼에 마우스를 올리거나 포커스를 맞추면 유효한 페이지 데이터를 사전 조회합니다.
    • 이전 페이지, 다음 페이지 및 개별 페이지 버튼의 사전 조회를 지원합니다.
    • 현재 페이지와 다른 페이지에 대해서만 사전 조회를 실행합니다.

@vercel

vercel Bot commented Aug 7, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
moving-frontend Ready Ready Preview Aug 7, 2026 2:24am
moving-frontend-p2ol Ready Ready Preview Aug 7, 2026 2:24am

@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 0a5cc1d6-7c20-4fae-a091-911d069bb82a

📥 Commits

Reviewing files that changed from the base of the PR and between f4ebd08 and d0e9653.

📒 Files selected for processing (2)
  • src/components/common/Pagination/Pagination.tsx
  • src/components/estimate/ReceivedRequestsPage.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/components/common/Pagination/Pagination.tsx

📝 Walkthrough

Walkthrough

Pagination에 페이지 프리페치 콜백을 추가했습니다. MoverDetailReviews는 해당 콜백으로 리뷰 페이지를 React Query 캐시에 미리 조회합니다. ReceivedRequestsPageFormEvent를 타입 전용 import로 변경합니다.

Changes

리뷰 페이지 프리페치

Layer / File(s) Summary
Pagination 프리페치 계약과 이벤트 처리
src/components/common/Pagination/Pagination.tsx
onPagePrefetch prop을 추가했습니다. 페이지 번호를 유효 범위로 보정합니다. 현재 페이지가 아닐 때 이전·개별·다음 페이지 버튼의 포인터 진입 및 포커스 이벤트에서 콜백을 호출합니다.
리뷰 쿼리 캐시 연결
src/components/mover/detail/MoverDetailReviews.tsx, src/components/estimate/ReceivedRequestsPage.tsx
React Query 클라이언트, 리뷰 API, 쿼리 키를 연결했습니다. 현재 mover와 페이지 정보로 리뷰 페이지를 prefetch하고 Pagination에 콜백을 전달합니다. FormEvent는 타입 전용 import로 변경했습니다.

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

Possibly related PRs

Suggested reviewers: 9g-g9

Sequence Diagram(s)

sequenceDiagram
  participant Pointer
  participant Pagination
  participant MoverDetailReviews
  participant ReactQuery
  participant getMoverReviews
  Pointer->>Pagination: 다른 페이지에 포인터 진입 또는 포커스
  Pagination->>MoverDetailReviews: 페이지 번호 전달
  MoverDetailReviews->>ReactQuery: 리뷰 쿼리 prefetch 요청
  ReactQuery->>getMoverReviews: mover와 페이지 정보로 API 호출
  getMoverReviews-->>ReactQuery: 리뷰 데이터 반환
  ReactQuery-->>MoverDetailReviews: 리뷰 데이터 캐시 저장
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 리뷰 페이지네이션에 prefetch를 적용한다는 핵심 변경을 정확하고 간결하게 설명합니다.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch perf/prefetch-mover-reviews

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.

🧹 Nitpick comments (1)
src/components/mover/detail/MoverDetailReviews.tsx (1)

57-65: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

리뷰 쿼리 옵션을 공통화해 주세요.

현재 useMoverReviewsprefetchReviewPage는 동일한 query key와 API 계약을 사용하므로 캐시 미스 문제는 없습니다. 다만 쿼리 계약이 중복되어 변경 시 불일치가 발생할 수 있습니다. 쿼리 옵션 팩토리 또는 전용 훅으로 공통화해 주세요.

🤖 Prompt for 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.

In `@src/components/mover/detail/MoverDetailReviews.tsx` around lines 57 - 65,
Extract the shared reviews query key and query function used by useMoverReviews
and prefetchReviewPage into a reusable query-options factory or dedicated hook,
then have both paths consume it. Anchor the change around prefetchReviewPage and
useMoverReviews, preserving moverId, page, and MOVER_REVIEW_PAGE_LIMIT in the
shared contract.

Source: Path instructions

🤖 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.

Nitpick comments:
In `@src/components/mover/detail/MoverDetailReviews.tsx`:
- Around line 57-65: Extract the shared reviews query key and query function
used by useMoverReviews and prefetchReviewPage into a reusable query-options
factory or dedicated hook, then have both paths consume it. Anchor the change
around prefetchReviewPage and useMoverReviews, preserving moverId, page, and
MOVER_REVIEW_PAGE_LIMIT in the shared contract.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 2b226bf0-d278-444c-92c9-d2109b9a29a6

📥 Commits

Reviewing files that changed from the base of the PR and between d54cfd4 and f4ebd08.

📒 Files selected for processing (2)
  • src/components/common/Pagination/Pagination.tsx
  • src/components/mover/detail/MoverDetailReviews.tsx

@juengseulki juengseulki 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.

전체 변경사항 확인했습니다!

👍 좋았던 점

  • 기사 상세 리뷰 페이지 이동 전에 대상 데이터를 미리 요청해 체감 전환 속도를 개선했습니다.
  • 기존 리뷰 조회 Query Key와 API 함수를 prefetch에도 동일하게 사용했습니다.
  • Query Key에 기사 ID, 페이지 번호, 페이지 크기를 모두 포함해 기존 useMoverReviews 캐시와 정확히 연결했습니다.
  • 프리패치 데이터가 별도 상태로 관리되지 않고 TanStack Query 캐시에서 자연스럽게 재사용되도록 구성했습니다.
  • hover 프리패치는 필수 작업이 아니므로 Promise를 기다리지 않고 비동기로 실행했습니다.
  • onPagePrefetch를 선택적 Prop으로 추가해 기존 Pagination 사용처에 영향을 주지 않았습니다.
  • 페이지 번호뿐 아니라 이전·다음 버튼에도 동일한 프리패치 동작을 적용했습니다.
  • 프리패치 대상 페이지를 유효 범위로 보정해 잘못된 페이지 요청을 방지했습니다.
  • 현재 페이지는 프리패치 대상에서 제외해 불필요한 호출을 줄였습니다.
  • 비활성화된 이전·다음 버튼에서도 결과적으로 현재 페이지와 같아져 추가 요청이 발생하지 않습니다.
  • 변경 파일이 두 개로 제한되어 있고 공통 Pagination과 실제 데이터 조회 화면의 책임도 잘 나뉘어 있습니다.
  • 현재 PR은 열려 있고 병합 가능한 상태이며, 한 개의 커밋으로 구성되어 있습니다.

🔍 확인 및 제안

현재 프리패치는 포인터 진입 기준으로만 실행됩니다.
따라서 키보드로 페이지 버튼에 포커스한 사용자는 클릭 전 프리패치 효과를 받지 못하지만,
클릭 시 기존 Query가 정상적으로 실행되므로 기능상 문제는 없습니다.

성능 경험까지 동일하게 제공하고 싶다면
페이지 번호와 이전·다음 버튼에 onFocus 프리패치를 함께 적용하는 것도 고려할 수 있습니다.

또한 hover가 매우 빠르게 여러 페이지를 지나가면
여러 페이지의 API 요청이 발생할 수 있습니다.
다만 Pagination에 표시되는 버튼 수가 제한적이고
TanStack Query가 동일 Query Key 요청을 중복 처리하지 않기 때문에
현재 범위에서는 과도한 네트워크 비용으로 이어질 가능성은 크지 않아 보입니다.

상세 정보와 리뷰 첫 페이지를 기사 카드 hover 시 함께 prefetch하는 개선은
현재 PR과 분리한 것이 적절해 보입니다.
그 작업은 목록 카드 수만큼 요청 가능성이 늘어날 수 있어,
staleTime, 사용자 의도 판단, 네트워크 비용을 별도로 검토하는 편이 좋습니다.

수고하셨습니다! 😊


To Reviewer 내용 기준으로 페이지 hover 시 사전 요청과
클릭 후 TanStack Query 캐시 재사용 흐름을 중점적으로 확인했습니다!

현재 구현에서는 페이지 번호나 이전·다음 버튼에 포인터가 진입하면
onPagePrefetch를 통해 대상 페이지 번호가 전달됩니다.

MoverDetailReviews에서는 해당 페이지 번호로 다음과 같은 Query를 미리 실행합니다.

  • 기존 리뷰 조회와 동일한 Query Key
  • 동일한 기사 ID
  • 동일한 페이지 번호
  • 동일한 MOVER_REVIEW_PAGE_LIMIT
  • 동일한 getMoverReviews() API 함수

따라서 hover 시 prefetch가 완료됐다면,
사용자가 해당 페이지를 클릭해 currentPage가 변경됐을 때
useMoverReviews가 같은 Query Key의 캐시 데이터를 재사용할 수 있는 구조입니다.

현재 페이지는 프리패치 대상에서 제외되고,
이전·다음 버튼도 경계에서 유효 페이지 범위로 보정되기 때문에
존재하지 않는 페이지에 대한 요청도 발생하지 않습니다.

프리패치 Promise를 기다리지 않으므로
사용자가 hover 직후 바로 클릭해도 이동 자체가 차단되지는 않습니다.

이 경우 prefetch가 먼저 완료됐다면 캐시를 즉시 사용하고,
아직 진행 중이라면 TanStack Query가 동일 Query Key의 진행 중 요청을 공유하는 흐름을 기대할 수 있습니다.

추가 성능 개선을 별도 작업으로 분리한 방향도 적절해 보입니다.

특히 기사님 찾기 카드 hover 시

  • 기사 상세
  • 리뷰 첫 페이지

를 모두 prefetch하면 사용자 체감은 좋아질 수 있지만,
카드를 빠르게 탐색할 때 요청량이 크게 늘어날 수 있습니다.

따라서 해당 개선은 다음 항목을 함께 검토한 뒤 진행하는 것이 좋겠습니다.

  • hover 지연 시간
  • staleTime
  • 네트워크 환경
  • 모바일에서는 hover가 없다는 점
  • 실제 상세 진입률
  • 여러 카드 연속 hover 시 요청량

@yooseohyeon

yooseohyeon commented Aug 7, 2026

Copy link
Copy Markdown
Contributor Author

@juengseulki
상세하게 리뷰해주셔서 항상 감사드립니다!
키보드 사용자도 동일한 경험을 제공하기 위해 페이지 번호와 이전/다음 버튼에 onFocus 프리패치를 추가했습니다!
여러 버튼을 빠르게 hover할 때의 요청 증가 가능성도 짚어주셔서 감사합니다. 말씀해주신 대로 현재 페이지네이션의 노출 버튼 수가 제한적이고 동일 query key 요청은 TanStack Query에서 공유되므로 이번 범위에서는 유지하겠습니다. 다만 요청량이나 성능 지표가 문제로 확인되면 hover delay 등을 별도 작업으로 검토해보겠습니다!
그리고 기사 카드 hover 시 상세·첫 리뷰 프리패치는 요청량이 늘어날 수 있고, 실제로 상세 페이지에서 진입하는 경우가 대부분인지 검토가 필요하기 때문에 후속 작업으로 분리하겠습니다.

전체 변경사항 확인했습니다!

👍 좋았던 점

  • 기사 상세 리뷰 페이지 이동 전에 대상 데이터를 미리 요청해 체감 전환 속도를 개선했습니다.
  • 기존 리뷰 조회 Query Key와 API 함수를 prefetch에도 동일하게 사용했습니다.
  • Query Key에 기사 ID, 페이지 번호, 페이지 크기를 모두 포함해 기존 useMoverReviews 캐시와 정확히 연결했습니다.
  • 프리패치 데이터가 별도 상태로 관리되지 않고 TanStack Query 캐시에서 자연스럽게 재사용되도록 구성했습니다.
  • hover 프리패치는 필수 작업이 아니므로 Promise를 기다리지 않고 비동기로 실행했습니다.
  • onPagePrefetch를 선택적 Prop으로 추가해 기존 Pagination 사용처에 영향을 주지 않았습니다.
  • 페이지 번호뿐 아니라 이전·다음 버튼에도 동일한 프리패치 동작을 적용했습니다.
  • 프리패치 대상 페이지를 유효 범위로 보정해 잘못된 페이지 요청을 방지했습니다.
  • 현재 페이지는 프리패치 대상에서 제외해 불필요한 호출을 줄였습니다.
  • 비활성화된 이전·다음 버튼에서도 결과적으로 현재 페이지와 같아져 추가 요청이 발생하지 않습니다.
  • 변경 파일이 두 개로 제한되어 있고 공통 Pagination과 실제 데이터 조회 화면의 책임도 잘 나뉘어 있습니다.
  • 현재 PR은 열려 있고 병합 가능한 상태이며, 한 개의 커밋으로 구성되어 있습니다.

🔍 확인 및 제안

현재 프리패치는 포인터 진입 기준으로만 실행됩니다. 따라서 키보드로 페이지 버튼에 포커스한 사용자는 클릭 전 프리패치 효과를 받지 못하지만, 클릭 시 기존 Query가 정상적으로 실행되므로 기능상 문제는 없습니다.

성능 경험까지 동일하게 제공하고 싶다면 페이지 번호와 이전·다음 버튼에 onFocus 프리패치를 함께 적용하는 것도 고려할 수 있습니다.

또한 hover가 매우 빠르게 여러 페이지를 지나가면 여러 페이지의 API 요청이 발생할 수 있습니다. 다만 Pagination에 표시되는 버튼 수가 제한적이고 TanStack Query가 동일 Query Key 요청을 중복 처리하지 않기 때문에 현재 범위에서는 과도한 네트워크 비용으로 이어질 가능성은 크지 않아 보입니다.

상세 정보와 리뷰 첫 페이지를 기사 카드 hover 시 함께 prefetch하는 개선은 현재 PR과 분리한 것이 적절해 보입니다. 그 작업은 목록 카드 수만큼 요청 가능성이 늘어날 수 있어, staleTime, 사용자 의도 판단, 네트워크 비용을 별도로 검토하는 편이 좋습니다.

수고하셨습니다! 😊

To Reviewer 내용 기준으로 페이지 hover 시 사전 요청과 클릭 후 TanStack Query 캐시 재사용 흐름을 중점적으로 확인했습니다!

현재 구현에서는 페이지 번호나 이전·다음 버튼에 포인터가 진입하면 onPagePrefetch를 통해 대상 페이지 번호가 전달됩니다.

MoverDetailReviews에서는 해당 페이지 번호로 다음과 같은 Query를 미리 실행합니다.

  • 기존 리뷰 조회와 동일한 Query Key
  • 동일한 기사 ID
  • 동일한 페이지 번호
  • 동일한 MOVER_REVIEW_PAGE_LIMIT
  • 동일한 getMoverReviews() API 함수

따라서 hover 시 prefetch가 완료됐다면, 사용자가 해당 페이지를 클릭해 currentPage가 변경됐을 때 useMoverReviews가 같은 Query Key의 캐시 데이터를 재사용할 수 있는 구조입니다.

현재 페이지는 프리패치 대상에서 제외되고, 이전·다음 버튼도 경계에서 유효 페이지 범위로 보정되기 때문에 존재하지 않는 페이지에 대한 요청도 발생하지 않습니다.

프리패치 Promise를 기다리지 않으므로 사용자가 hover 직후 바로 클릭해도 이동 자체가 차단되지는 않습니다.

이 경우 prefetch가 먼저 완료됐다면 캐시를 즉시 사용하고, 아직 진행 중이라면 TanStack Query가 동일 Query Key의 진행 중 요청을 공유하는 흐름을 기대할 수 있습니다.

추가 성능 개선을 별도 작업으로 분리한 방향도 적절해 보입니다.

특히 기사님 찾기 카드 hover 시

  • 기사 상세
  • 리뷰 첫 페이지

를 모두 prefetch하면 사용자 체감은 좋아질 수 있지만, 카드를 빠르게 탐색할 때 요청량이 크게 늘어날 수 있습니다.

따라서 해당 개선은 다음 항목을 함께 검토한 뒤 진행하는 것이 좋겠습니다.

  • hover 지연 시간
  • staleTime
  • 네트워크 환경
  • 모바일에서는 hover가 없다는 점
  • 실제 상세 진입률
  • 여러 카드 연속 hover 시 요청량

@yooseohyeon
yooseohyeon merged commit d2843c5 into dev Aug 7, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants