React 앱이 느려지는 이유와 해결 방법

카테고리

프로그래밍/소프트웨어 개발

서브카테고리

웹 개발

대상자

React 개발자 (중급~고급 수준)

핵심 요약

  • 불필요한 리렌더링 방지: React.memo 사용으로 props 변경 시만 리렌더링
  • 대량 목록 처리 최적화: react-window 또는 react-virtualized로 가시 영역만 렌더링
  • 코드 분할 및 지연 로딩: React.lazySuspense로 초기 로딩 시간 단축
  • useEffect 의존성 배열 관리: useRef로 상태 변경 없이 유지할 값 사용
  • 성능 프로파일링: React Developer Tools의 Profiler로 리렌더링 병목 지점 확인

섹션별 세부 요약

1. 불필요한 리렌더링

  • Math.random()과 같은 변동 props로 인한 무한 리렌더링
  • React.memoprops 변경 시만 리렌더링
  • const MyComponent = React.memo(({ someProp }) => { ... }) 구현 예시

2. 대량 목록 렌더링

  • .map()으로 생성된 목록이 화면 외 영역까지 렌더링
  • react-windowFixedSizeList로 가시 영역만 렌더링
  • {({ index, style }) => ( )} 컴포넌트 생성 방식 예시

3. 초기 로딩 시간 최적화

  • 모든 컴포넌트와 자바스크립트 파일을 동시에 로딩
  • React.lazy(() => import('./HeavyComponent'))로 코드 분할
  • Loading...}> 사용 예시

4. useEffect의 의존성 관리

  • 의존성 배열이 잘못 설정되면 무한 리렌더링 발생
  • useRef로 상태 변경 없이 유지할 값 사용
  • useEffect(() => { ... }, [dependency]) 패턴 적용

5. 성능 프로파일링

  • React Developer Tools의 Profiler 사용
  • performance.mark()와 콘솔 로그로 병목 지점 분석
  • StrictMode로 개발 시 예상치 못한 동작 감지

결론

  • useCallback으로 콜백 함수를 메모이즈하여 props 변경 방지
  • JSX 내 익명 함수 사용 최소화
  • 컴포넌트 계층 구조를 평탄하게 유지
  • Profilerperformance.mark()로 병목 지점 분석 후 최적화
  • React 앱의 성능은 리렌더링 최적화, 코드 분할, 프로파일링을 통해 극복 가능