Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Warning
|
| Cohort / File(s) | 요약 |
|---|---|
탭 렌더링 변경frontend/src/pages/ClubDetailPage/ClubDetailPage.tsx |
ClubIntroContent와 ClubFeed를 항상 마운트하도록 변경하고, 활성 탭에 따라 인라인 display 스타일로 가시성 토글(조건부 렌더링 제거). 불필요한 React 훅 import 정리. |
이미지 로딩 임계값 (디바이스 기반)frontend/src/pages/ClubDetailPage/components/ClubFeed/ClubFeed.tsx |
useDevice 도입, DESKTOP_EAGER_IMAGE_COUNT = 15, MOBILE_EAGER_IMAGE_COUNT = 6 추가. 디바이스에 따라 loadingThreshold 계산 후 loading={index < loadingThreshold ? 'eager' : 'lazy'} 적용. 기존 피드/모달 로직은 유지. |
매니페스트 / 패키지 변경package.json |
메타 변경(라인 수 소폭 조정). |
Estimated code review effort
🎯 3 (Moderate) | ⏱️ ~20 minutes
Possibly related issues
- [refactor] MOA-536 활동사진을 최적화한다 #1072 — ClubFeed의 이미지 로딩 최적화(디바이스 기반 eager/lazy)와 직접적으로 일치하므로 연계 가능성 있음.
- MOA-536 — 활동사진 최적화 목표와 관련된 작업으로 연결될 수 있음.
Possibly related PRs
- [feature] 상세 페이지 모바일 탑바 웹뷰로 이관 및 리액트 네이티브 API 연동 구조 도입 #1090 — ClubDetailPage 관련 변경을 함께 수정하므로 코드 수준 연관성 있음.
- [feature] 상세페이지 소개 내용 및 FAQ 컴포넌트 구현 #959 — ClubIntro/Photos 렌더링 방식 변경과 유사한 영역을 다루므로 관련 있음.
Suggested reviewers
- lepitaaar
- seongwon030
- oesnuj
🚥 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 | 제목은 PR의 주요 변경 사항인 활동사진 최적화를 명확하게 요약하고 있습니다. |
| Linked Issues check | ✅ Passed | 코드 변경이 MOA-536에서 요구하는 활동사진 탭의 이미지 표시 지연 개선 요구사항을 충족합니다. |
| Out of Scope Changes check | ✅ Passed | 모든 변경사항이 활동사진 최적화라는 정의된 범위 내에 있으며 불필요한 변경이 없습니다. |
| Docstring Coverage | ✅ Passed | No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. |
✏️ Tip: You can configure your own custom pre-merge checks in the settings.
✨ Finishing touches
- 📝 Generate docstrings
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.
Comment @coderabbitai help to get the list of available commands and usage tips.
lepitaaar
left a comment
There was a problem hiding this comment.
이미지 최적화 코드 잘읽었습니다. 저도 접속할때마다 저부분이 늦게 로딩돼서 ux 개선이 필요하다 느꼈던 부분인데 좋은거같네요. 다만 eager, lazy의 임계값 기준을 따로 측정을 통해 설정하신건지 궁금합니다. 휴대폰 + 느린 인터넷환경일때도 퍼포먼스적인 차이가없으면 수치를 조금 늘려도 될꺼같다 생각이드네요. 수고하셨습니다
frontend/src/pages/ClubDetailPage/components/ClubFeed/ClubFeed.tsx
Outdated
Show resolved
Hide resolved
eager, lazy 임계값 기준은 제가 여러 기기를 확인해보면서 임의로 정한 값입니다ㅏ 대부분의 기기에서 문제가 없을 것 같아 그렇게 정했는데, 성능적인 큰 차이가 있는 것은 아니라서 수정하면 될 것 같습니다 |
seongwon030
left a comment
There was a problem hiding this comment.
많은 고민을 하셨군요 ~ 백엔드에서 캐시서버를 둬도 속도가 늦어진 것 봐서는 또다른 최적화가 필요할 것 같네요. 한 번 더 고민해보죠 !
| const loadingThreshold = useMemo(() => { | ||
| if (isDesktop || isLaptop) return 15; | ||
| return 6; | ||
| }, [isDesktop, isLaptop]); |
There was a problem hiding this comment.
말씀 주신 것처럼 15, 6은 맥락이 없으면 매직 넘버로 보일 수 있겠네요...
상수로 분리하는 것이 더 명확해보이고 이후 최대 이미지 수가 변경되더라도 수정하기에 더 편할 것 같다는 생각이 드네요
해당 값들은 기기별로 eager 로딩할 이미지 개수를 의미합니다ㅏ
직접 측정해보며 데스크톱/노트북에서는15장의 이미지 전체가 한 눈에 보이는 구조이고, 그 외의 디바이스는 상단의 일부 이미지가 먼저 보이는 구조라 네트워크 비용을 고려해 6으로 설정했습니다
말씀 주신 방향대로 반영하겠습니다! 481812d
|
|
||
| <Styled.TabContent> | ||
| {activeTab === TAB_TYPE.INTRO && ( | ||
| <div style={{ display: activeTab === TAB_TYPE.INTRO ? 'block' : 'none' }}> |
There was a problem hiding this comment.
마운트/언마운트하지 않고 미리 렌더링해 둔 상태에서 display로만 제어하셨군요! 좋은 아이디어 같습니다 👍
렌더링 관점에서도 불필요한 재렌더를 줄일 수 있어 좋은 선택인 것 같습니다
There was a problem hiding this comment.
감사합니다!!
저도 최적화 관련해서 수치적으로 개선된 효과를 보여줄 수 있으면 좋겠다고 생각했는데,
Lighthouse를 통해서 비교해볼 수 있군요! 좋은 정보 감사해요~
확인해보고 PR에 추가해두겠습니당
There was a problem hiding this comment.
https://www.notion.so/2f969c6c480d8036bf10cd12420b0b7c?source=copy_link 에 성능 최적화와 관련한 글을 정리해두었으니 확인해보시면 될 것 같아요!
#️⃣연관된 이슈
📝작업 내용
성능 측정
https://www.notion.so/2f969c6c480d8036bf10cd12420b0b7c?source=copy_link
default.mp4
문제 배경
동아리 상세페이지에서
소개 내용 탭 -> 활동사진 탭으로 전환할 때 이미지가 늦게 표시되는 문제가 있었습니다.
기본 구조에서는 활동 사진 탭이 클릭 시점에
ClubFeed컴포넌트가 처음 마운트되며, 그때<img src="...">가 생성되어 이미지 네트워크 요청이 탭 클릭 이후에 시작되는 구조였습니다.이로 인해 탭 전환 시 빈 영역이 잠시 보였다가 이미지가 하나씩 나타나는 체감 지연이 발생했습니다.
1️⃣ 1차 시도 : TanStack Query prefetchQuery
시도 목적
탭 전환 전에 필요한 리소스를 미리 준비하여 활동 사진 탭 진입 시 체감 지연을 줄이고자 했습니다.
결과
이미지 로딩 속도와 탭 전환 체감 모두 개선되지 않았습니다.
실패 원인
prefetchQuery는 데이터만 관리하고,<img>태그를 생성하지 않아서 문제는 데이터가 아니라 이미지 로딩 시점에 있다는 것을 깨달았습니다.2️⃣ 2차 시도 : 이미지 리소스 preload (
new Image())접근 방식
이미지 DOM 생성과 무관하게 이미지 네트워크 요청을 상세페이지 진입 시점에 선행하도록 변경했습니다. 활동 소개 탭이 보이는 동안에도 활동사진 이미지를 백그라운드에서 미리 다운로드 받도록 했습니다.
결과
이미지 네트워크 요청이 탭 클릭 이전에 시작되도록 하여 활동사진 탭 클릭 시 이미지가 캐시에서 바로 사용되도록 했습니다.
이전보다 로딩 속도가 빨라진 것 같았지만, 중간 중간 지연되는 느낌을 받았습니다.
한계
왜 지연되는건지 생각을 해보다가
ClubFeed컴포넌트는 여전히 탭 클릭 시에 처음 마운트되는 것으로, 이미지를 미리 받아뒀지만 탭 클릭 시점의 렌더링 지연이 제거되지 않았습니다.3️⃣ 최종 : 컴포넌트 프리마운트(Hidden DOM 활용)
접근 방식
2차 시도를 통해 단순한 이미지 preload만으로는 탭 클릭 시 발생하는 지연을 완전히 제거할 수 없다는 점을 확인했습니다.
따라서 이미지를 포함한 컴포넌트 자체를 상세페이지 진입 시점에 미리 마운트하도록 했습니다. 두 탭의 컴포넌트를 모두 초기 렌더 시에 마운트하도록 했고, 탭 전환은
display속성으로만 제어했습니다.결과
활동 사진 컴포넌트가 이미 마운트된 상태로,
<img>태그 역시 DOM에 이미 존재하여 활동 사진 탭 클릭 시 렌더링 지연 없이 즉시 이미지가 표시되도록 했습니다.이 방식은 초기 렌더 시 메모리 사용량이 다소 증가하고, 보이지 않는 컴포넌트까지 함께 마운트된다는 점에서 비효율적일 수 있지만, 활동 사진 탭 진입 시 발생하던 체감 지연을 제거하는 것을 최우선으로 두고, 이미지가 핵심 콘텐츠인 화면 특성상 UX 관점에서의 즉각적인 반응형 개선을 우선으로 한 선택입니다.
현재 활동사진이 최대 15장인 것을 고려했을때 수용 가능한 비용이라 판단했습니다.
4️⃣ 추가 최적화: 기기별 eager / lazy 로딩 분기
프리마운트 상태에서도 화면에 바로 보일 가능성이 높은 이미지만 eager하고, 나머지는 lazy로 두어 네트워크 비용을 절감하도록 했습니다.
논의하고 싶은 부분(선택)
여전히 느린 이미지 존재
프론트 단에서는 가능한 최적화를 최대한 적용해보았으며, 현재 남아 있는 일부 지연은 이미지 파일 자체 용량이 2MB 이상인 것에서 기인한 것으로 생각됩니다.
이는 서버에서 피드용 이미지 리사이즈 및 압축, CDN 이미지 변환 등을 통해 해결해볼 수 있다고 하니 생각해보면 좋을 것 같습니다!
🫡 참고사항
Summary by CodeRabbit
✏️ Tip: You can customize this high-level summary in your review settings.