Skip to content

Conversation

@Pheejung
Copy link

@Pheejung Pheejung commented Dec 23, 2025

과제 체크포인트

과제 요구사항

  • 배포 후 url 제출
    https://pheejung.github.io/front_7th_chapter4-2/

  • API 호출 최적화(Promise.all 이해)

  • SearchDialog 불필요한 연산 최적화

  • SearchDialog 불필요한 리렌더링 최적화

  • 시간표 블록 드래그시 렌더링 최적화

  • 시간표 블록 드롭시 렌더링 최적화

과제 셀프회고

기술적 성장

1. React 성능 최적화 패턴 학습

이번 과제에서 가장 큰 배움은 React의 렌더링 메커니즘을 깊이 이해하게 된 점이었습니다. 단순히 useMemouseCallback을 사용하는게 아닌, 컴포넌트 간 데이터 흐름과 의존 관계를 구조적으로 분석하면서 리렌더링이 발생하는 근본 원인을 파악하려고 노력했습니다.
React.memo를 통해 불필요한 렌더링을 방지하고, useCallback으로 핸들러 참조의 불안정성을 최소화했습니다. 특히 Context 사용 시, 구독 범위가 넓어질수록 리렌더링 비용이 급격히 커진다는 문제를 체감했고, Context 분리 전략을 통해 상태 구독 단위를 세분화했습니다. 이를 통해 렌더링 횟수를 눈에 띄게 줄일 수 있었습니다.

2. 상태 관리 최적화

이전에는 useState 중심으로 상태를 관리했지만, 이번에는 참조 안정성을 유지하기 위해 useRef 기반의 캐싱 전략을 적극 도입했습니다.
또한 이벤트 핸들러 관리에서 레지스트리 패턴을 적용하여, 특정 이벤트의 변경이 전체 렌더 트리에 영향을 주지 않도록 구조화했습니다. 이 과정에서 ‘상태는 최소화하되, 동작은 최대한 지역화해야 한다’는 원칙의 중요성을 체감했습니다.

3. 컴포넌트 설계 개선

리렌더링 최적화의 핵심은 결국 컴포넌트의 독립성 확보라는 점을 깨달았습니다.
이를 위해 정적 데이터만을 표현하는 컴포넌트(Static)와 사용자 입력·이벤트에 반응하는 동적 컴포넌트(Dynamic)를 명확히 분리했습니다.
이로써 리렌더링의 전파 범위를 줄이고, 재사용성과 유지보수성을 동시에 확보할 수 있었습니다. 또한 Props drilling 문제를 Context로 일부 해소하면서도, Context의 오남용으로 인한 전역 리렌더링 문제를 피하기 위해 최소 구독 구조로 관리했습니다.

코드 품질

1. 모듈화 및 관심사 분리

기존에는 하나의 파일에서 다수의 역할을 수행하던 코드를, 각자의 책임 단위로 분리했습니다.
예를 들어, ScheduleTableLayout을 별도 모듈로 분리하여 UI 구조와 데이터 로직의 결합도를 낮췄고, SearchDialogContext를 통해 모달의 열림/닫힘 상태를 전역적으로 관리하면서도 불필요한 상태 공유를 방지했습니다.
이런 구조적 분리를 통해 코드의 가독성, 테스트 용이성, 재사용성이 크게 향상되었습니다.

2. 성능 최적화

드래그/드롭 시 전체 테이블이 리렌더링되는 문제를 해결하기 위해, 변경된 셀만 리렌더링되도록 key 기반 렌더링 제어를 추가했습니다.
또한 모달의 상태 변화가 상위 컴포넌트에 불필요하게 영향을 주지 않도록, 상태를 독립된 Context로 분리했습니다.

학습 효과 분석

이번 과제를 통해 단순히 “리렌더링을 줄였다”는 개념적인 부분 외에도 React의 내부 렌더링 트리 구조와 메모이제이션의 한계를 명확히 이해하게 되었습니다.
Context API가 전역 상태 공유에는 편리하지만, 모든 구독자가 함께 리렌더링되는 구조적 한계를 갖고 있다는 점을 실험을 통해 직접 체감했습니다.
React DevTools의 “Highlight updates” 기능을 활용해 렌더링 범위를 시각적으로 확인하며, 문제의 원인을 탐색하고 개선 방향을 즉각 검증할 수 있었습니다.

과제 피드백

이번 과제는 단순히 기능 구현이 아니라, 실제 프로덕션 수준의 성능 문제를 직접 마주하고 해결하는 경험이었습니다.
React 애플리케이션은 프로젝트가 커질수록 구조적 복잡도와 렌더링 비용이 함께 증가하는데, 이를 체계적으로 관리하기 위한 전략이 얼마나 중요한지를 실감했습니다.
여러 최적화 기법을 실전에 적용하면서 “왜 최적화해야 하는지”에 대한 감각이 생겼습니다.
즉, 불필요한 리렌더링을 막는 것이 목적이 아니라, 유지보수성과 확장성까지 고려한 구조적 개선이 진짜 최적화라는 점을 깨달았습니다.

리뷰 받고 싶은 내용

설계적 관점에서의 최적화

  • Context 분리, memoization, 컴포넌트 구조 개선 등 다양한 최적화 기법 중 우선순위를 어떻게 두는지, 즉 “무엇부터 최적화하는 게 가장 효율적인지” 피드백을 받고 싶습니다.
  • 상태 관리와 렌더링 성능을 동시에 고려할 때 Context + memoization” 조합이 최선인지 혹은 “Recoil, Jotai, Zustand 같은 전역 상태 관리 라이브러리”로 전환하는 게 더 바람직한지 궁금합니다.

Pheejung added 3 commits December 23, 2025 21:58
- lectureService에서 Promise.all을 사용한 병렬 API 호출 및 캐싱 구현
- useLectures 훅으로 데이터 로딩 및 에러 처리 추가
- SearchDialog에 useMemo, useCallback, React.memo 적용으로 최적화
- 폴더 구조 개선: hooks를 src/hooks/, services를 src/services/로 이동
- ScheduleTable에서 useDndContext로 드래그 상태 감지
- 드래그 중 getColor useCallback 메모이제이션으로 리렌더링 감소
- ScheduleTables에 React.memo 적용으로 드롭 최적화
Pheejung and others added 14 commits December 24, 2025 00:27
- DraggableSchedule을 별도 모듈로 이동하고 React.memo로 래핑
- ScheduleTables에서 TableCard로 테이블별 콜백을 안정화
- SearchDialog: useFilteredLectures, React.memo, useMemo/useCallback 적용
- 드래그 최적화: Context 분리 및 해당 테이블만 리렌더링되도록 개선
- ScheduleTables: tableEntries 및 disabledRemoveButton 메모이제이션
- ScheduleContext: reducer 최적화 및 불필요한 업데이트 방지
시간표 드래그 최적화:
- 드래그 시 해당 시간표 테이블만 리렌더링
- useScheduleTable hook으로 개별 테이블 구독
- TableOutline 컴포넌트 최적화

SearchDialog 최적화:
- 필터 컴포넌트 분리 및 React.memo 적용
- useFilteredLectures 의존성 최적화
- 검색 조건 변경 시 해당 필터만 리렌더링
- 검색 결과 테이블 컴포넌트 분리

무한 스크롤 성능 개선:
- requestAnimationFrame으로 스크롤 이벤트 최적화
- LectureRow 컴포넌트 메모이제이션
- IntersectionObserver rootMargin 적용
- IntersectionObserver 최적화
- LectureRow 컴포넌트 메모이제이션
- CSS 최적화 (willChange, contain)
- 모달 열기/닫기 시 테이블 리렌더링 방지
  - SearchDialogContext 생성하여 searchInfo 상태 분리
  - ScheduleTables에서 searchInfo 상태 제거
  - SearchDialog를 App 레벨로 이동하여 독립적으로 관리

- 셀 렌더링 최적화
  - ScheduleTableLayout을 별도 파일로 분리
  - 클릭 핸들러 레지스트리 패턴 도입
  - 모든 셀 컴포넌트를 React.memo로 최적화
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant