Conversation
같은 study_members 행을 화면마다 다른 queryKey로 조회하고 있었다. TanStack Query는 queryKey로만 캐시를 찾고 queryFn이 같은지는 보지 않으므로, 이름이 갈린 만큼 같은 응답이 별개 엔트리로 저장되고 요청도 각각 나갔다. ["userInfo"] mypage/page, Sidebar ["myInfo"] MySolves, problems/page ["myInfoInAccountSetting"] AccountSetting ["getMyMemberInfo"] ProfileSetting, StudySetting lib/query/useMyMemberInfo.ts 에 키와 훅을 한 번만 정의하고 전 호출부를 교체했다. 컴포넌트 위치는 그대로 두었다. 캐시가 전역이라 키만 맞으면 공유되므로 상위로 끌어올려 props로 내릴 이유가 없다. - getMyMemberInfo 중복 구현 제거(api/members.ts). 스터디 미참여 시 throw 대신 null을 돌려주는 api/study.ts 쪽을 남겼다. 참여/생성 화면 전환이 null에 걸려 있다. - ProfileSetting의 invalidateQueries 3줄 → 1줄. 키가 하나라 구독자가 함께 갱신된다. - problems/page의 ["memberList"]에 studyId를 넣고 enabled를 걸었다. studyId 없이 실행되면 에러 상태로 굳고, 키가 고정이라 재조회도 되지 않았다. 측정(로그인 상태, 개발 서버): /settings 요청 10건 → 6건 (study_members?select=* 3회 → 1회) /mypage 요청 12건 → 10건 (study_members?select=* 2회 → 1회) 검증: tsc --noEmit 0 / bun test 12 pass / biome 변경 파일 0 error Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Heatmap/service.ts 와 LineChart/service.ts 가 완전히 같은 쿼리를 돌리고 있었다.
supabase.from("problems").select("date").eq("member_id", memberId)
키가 ["heatmap"] / ["lineGraph"]로 갈려 있어 캐시가 공유되지 않고
마이페이지 한 번 로드에 같은 SQL이 두 번 나갔다.
lib/query/useProblemDates.ts 로 키를 합치고, 화면별 집계는 select로 갈랐다.
select는 화면마다 다르므로 인자로 받되 호출부에서 useCallback으로 감쌌다.
(기존 인라인 화살표는 렌더마다 정체성이 바뀌어 집계가 매번 다시 돌았다)
- countByDate / countByMonth 를 각 hook.ts에 순수 함수로 추가하고 테스트를 붙였다.
기존 createAndFillHeatmap / createSixMonthObject 시그니처는 건드리지 않아
타임존 경계값 테스트가 그대로 유지된다.
- countByMonth는 'YYYY-MM-DD' 문자열 앞 7자를 자른다. 기존 구현은
new Date(date).toISOString().slice(0,7)로 Date를 거쳤는데, 되돌릴 이유가 없다.
- 중복 service 2개 삭제.
측정(로그인 상태, 개발 서버):
/mypage 요청 12건 → 9건. 중복 엔드포인트 0건(모든 요청이 1회)
화면 확인: 월별 축 3~8월 6개, 난이도 막대 3개, 히트맵 합계 8건,
말일(2026-05-31) 셀 보존
검증: tsc --noEmit 0 / bun test 18 pass
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
자동 PR 코드 리뷰
검증 결과이번 PR 영향 가능 항목이번 PR 변경 파일에서 직접 발생한 것으로 보이는 항목은 없습니다. 기존 실패로 추정되는 항목기존 실패로 분류된 항목은 없습니다. 경고
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
같은 데이터를 화면마다 다른
queryKey로 조회하고 있어, 한 페이지 로드에 동일한 요청이 여러 번 나가고 있었습니다.TanStack Query의 캐시는
queryKey로만 조회합니다.queryFn이 같은 함수인지는 보지 않습니다. 키 이름이 갈린 만큼 같은 응답이 별개 엔트리로 저장되고, 요청도 각각 나갑니다.무엇이 갈려 있었나
1)
getMyMemberInfo— 같은study_members행이 키 4개["userInfo"]mypage/page.tsx,Sidebar.tsx["myInfo"]MySolves/view.tsx,problems/page.tsx["myInfoInAccountSetting"]AccountSetting/view.tsx["getMyMemberInfo"]ProfileSetting/view.tsx,StudySetting/view.tsx구현도
api/members.ts와api/study.ts에 두 벌 있었습니다.2) 히트맵 / 월별 차트 — 완전히 같은 SQL이 키 2개
Heatmap/service.ts와LineChart/service.ts가 둘 다problems.select("date").eq("member_id", …)를 돌리고 뒤에서 집계만 다르게 하고 있었습니다.어떻게 고쳤나
src/lib/query/에 키와 훅을 한 번만 정의하고 호출부를 교체했습니다.useMyMemberInfo()—MY_MEMBER_INFO_KEY하나useProblemDates(memberId, select)— 원본은 한 번 받고 화면별 집계는select로 분기컴포넌트 위치는 그대로 뒀습니다. 캐시가 전역이라 키만 맞으면 공유되므로, 상위로 끌어올려 props로 내릴 이유가 없습니다.
측정 (로그인 상태, 개발 서버)
performance.getEntriesByType('resource')로 Supabase 요청만 집계했습니다./settingsstudy_members?select=*3회)/mypagestudy_members?select=*2회,problems?select=date2회)/mypage는 이제 모든 엔드포인트가 정확히 1회입니다.곁다리로 같이 고쳐진 것
ProfileSetting의invalidateQueries3줄 → 1줄. 사본이 넷이라 손으로 나열하다가["myInfo"]와["myInfoInAccountSetting"]두 개가 빠져 있었습니다. 그 둘은.id/.study_id만 읽고 있어 화면에 드러나는 문제는 없었지만, 이름을 읽는 컴포넌트가 하나라도 붙으면 그때 터집니다.problems/page.tsx의["memberList"]에studyId추가 +enabled게이트.studyId없이 첫 렌더에서 실행돼 에러 상태로 굳고, 키가 고정이라 재조회도 되지 않던 자리였습니다.getMyMemberInfo중복 구현 제거. 스터디 미참여 시throw하던api/members.ts쪽을 지우고null을 돌려주는api/study.ts쪽을 남겼습니다. 참여/생성 화면 전환이null에 걸려 있습니다.countByMonth는 문자열을 자릅니다. 기존 구현은new Date(date).toISOString().slice(0,7)로 Date를 한 번 거쳤는데,'YYYY-MM-DD'에서 앞 7자를 자르면 되는 일이라 되돌릴 이유가 없었습니다.검증
createAndFillHeatmap과createSixMonthObject의 시그니처는 건드리지 않아 기존 타임존 경계값 테스트가 그대로 유지됩니다. 집계 단계를 순수 함수로 새로 빼고 거기에 테스트를 붙였습니다.화면 확인 (
/mypage): 월별 축 3~8월 6개, 난이도 막대 3개, 히트맵 합계 8건, 말일(2026-05-31) 셀 보존.남은 것 (이 PR 범위 밖)
PlatformChart/service.ts에getLineGhDataMonth세 번째 사본이 있습니다.PieChartWithCustomizedLabel이mypage/page.tsx에서 주석 처리돼 있어 지금은 실행되지 않아 건드리지 않았습니다.🤖 Generated with Claude Code