Conversation
|
✅ Storybook이 배포되었습니다. |
| const handleNavigateReport = useCallback(() => { | ||
| navigate(routePath.REPORT); | ||
| }, [navigate]); |
There was a problem hiding this comment.
이 부분에서 useCallback이 꼭 필요할까? 라는 의문이 들었어요!
현재 handleNavigateReport는 memoized 된 컴포넌트에 전달되지 않고 이 PR의 핵심 개선 포인트가 리렌더링 최적화가 아닌 repaint 범위 분리에 있는 만큼 단순 함수로 구현해도 동작 및 성능 측면에서 문제는 없을 것 같아 보여욥!
jeonghoon11
left a comment
There was a problem hiding this comment.
이번 PR을 통해 컴포넌트 분리가 repaint 범위 축소에 어떤 효과를 줄 수 있는지 이해할 수 있었네요 굿굿!
jogpfls
left a comment
There was a problem hiding this comment.
컴포넌트 분리가 이렇게 중요한지 처음 알았네요.. 코드리뷰 하려고 PR 읽으면서 여러모로 공부가 많이 되었어요!! 👍
| interface StaticContentProps { | ||
| userName?: string; | ||
| productName?: string; | ||
| company?: string; | ||
| keywordChips?: string[]; | ||
| } | ||
|
|
||
| /** 보험 추천받은 유저가 볼 화면 */ | ||
| export const RecommendedInfoSection = ({ | ||
| const StaticContent = ({ |
There was a problem hiding this comment.
따로 이 컴포넌트들을 파일로 분리 안하신 이유가 있나요?!
There was a problem hiding this comment.
파일 분리를 고민하다가, 재사용 목적이 아니고 분산시킬 필요성이 우리 눈에 깔끔한 거라면 불필요하다고 생각했어요.
StaticContent, BottomButton 이 이 파일에서만 쓰이는 로컬 UI 이기 때문에 같은 파일에 두어서 지역성을 유지하는 게 낫다고 생각했는데, 요 부분은 코드리뷰에서 논의해보고 싶었어요. 혜린님은 분리하는 게 좋다고 생각하시나요!
📌 Summary
해당 PR에 대한 작업 내용을 요약하여 작성해주세요.
Carousel의 autoPlay 동작으로 인해 RecommendedInfoSection 전체가 매 프레임 업데이트 감지(Highlight) 되던 문제를 해결했습니다.
문제의 원인이 React 리렌더가 아닌 브라우저 repaint 범위 확장에 있음을 확인하고,
repaint 범위를 Carousel 영역으로 한정하도록 구조를 개선했습니다.
📚 Tasks
문제점
캐러셀의 autoPlay 기능이 캐러셀 렌더링만 담당하지 않고 Recommended-info-section 안에 있는 모든 컴포넌트에 대해서 React Profiler 의 rendering Highlight 에 계속 감지가 되는 문제가 있었습니다.
이게 리렌더링인지, 리페인트인지 무한으로 highlight 되고 있어서 해당 문제를 해결해야겠다고 생각했어요.
2025-12-24.18.48.16.mov
문제 원인 파악
처음에는 리렌더링이 원인이라고 판단했어요. 그래서 리렌더링 여부를 확인하기 위해, 전체 부모 컴포넌트인 RecommendedInfoSection과 내부 요소인 InsuranceSubtitle에 console.count()를 찍어 렌더 횟수를 확인했습니다.
아래와 같이 매 프레임마다 count가 증가하지 않았고, 즉 매 프레임 리렌더링이 발생하는 상황이 아니라는 것을 먼저 확인할 수 있었어요.
Profiler는 크게 다음을 보여줍니다.
Profiler에서 카운트가 계속 증가하는 것은 RecommendedInfoSection이 매 프레임 다시 렌더되고 있어서가 아니라, Carousel의 autoplay 애니메이션이 매 프레임 state 업데이트를 발생시키고 → 그 결과 React commit이 계속 일어나고 있었기 때문이었습니다.
즉,
Carousel 의 transtform 이 변경되면 브라우저가 전체 section 을 하나의 페인팅 단위로 인식할 수 있어요.
그래서 브라우저가 변경 범위를 정확히 구분하지 못해 전체 영역을 리페인트 할 수 있습니다.
해결 방향 - repaint 범위 제한
다음과 같이 분리하여 각 컴포넌트가 독립적인 Fiber 노드가 되어 브라우저가 각 부분을 독립적인 레이어로 인식할 수 있도록 했어요.
따라서 최적화의 목표를 리렌더를 줄이는 것이 아니라, Carousel 애니메이션으로 인해 발생하는 repaint 범위를 최소화하는 것 으로 바꾸었습니다.
repaint 를 줄이기 위해 StaticContent, Carousel, BottomButton 등 역할 단위로 분리하여
애니메이션이 발생하는 영역을 기준으로 브라우저가 자주 바뀌는 영역만 인식할 수 있도록 repaint 범위를 격리했어요.
결과적으로 이전에는 모든 요소가 매 프레임 repaint 되었다면, 개선 이후에는 repaint 범위가 carousel 로 국한되면서 불필요한 화면 갱신 비용을 낮출 수 있었습니다.
[As Is]
2025-12-24.18.48.16.mov
[To-Be]
2025-12-30.00.08.26.mov