React · 2026-04-14

React 렌더 사이클 이해와 성능 최적화 포인트

렌더 사이클과 Virtual DOM 동작을 중심으로 React 성능 최적화 포인트를 체계적으로 정리한 실무 전략

작성일 : 2026-04-14 ㆍ 작성자 : 관리자
post
목차

서론: 왜 렌더 사이클을 이해해야 하는가

컴포넌트가 언제, 왜 재렌더링되는지 모르면 성능 문제를 해결하기 어렵다. 특히 사용자 인터랙션이 많거나 데이터가 빈번히 바뀌는 앱에서는 작은 렌더 비용이 누적되어 체감 성능 저하로 이어진다. 따라서 react 렌더 사이클 이해는 최적화 우선순위를 정하는 기초가 된다.

렌더 사이클의 기본 흐름

상태 변화에서 DOM 반영까지

렌더 사이클은 일반적으로 상태 변경으로 시작한다. setState나 props 변화가 발생하면 해당 컴포넌트의 렌더 함수가 호출된다. 이후 React는 Virtual DOM에서 변경점을 계산하고 실제 DOM에 최소한의 변경만 반영한다. 이 흐름을 이해하면 어디에서 비용이 발생하는지 파악하기 쉽다.

주요 단계

  • 업데이트 트리거: setState, props 변경, 컨텍스트 업데이트
  • 렌더 단계: 컴포넌트 render/functional body 실행
  • 리콘실리레이션: Virtual DOM 비교(diff)
  • 커밋 단계: 실제 DOM에 변경 적용

Virtual DOM과 렌더 비용

Virtual DOM은 실제 DOM 변경을 줄여준다. 그러나 Virtual DOM 생성과 비교도 비용이 있다. 그래서 virtual dom 렌더링 최적화가 중요하다. 특히 대형 컴포넌트 트리에서 불필요한 재계산이 많아지면 오히려 성능 저하가 발생한다.

주의할 점

  • 불필요하게 큰 컴포넌트 트리는 매 렌더마다 많은 작업을 유발한다.
  • 렌더 시 계산이 복잡하면 CPU 비용이 커진다.
  • 자주 바뀌는 state를 최상위에 두면 하위 컴포넌트 전체가 재렌더링된다.

성능 최적화 포인트 react: 핵심 전략

성능 최적화는 다양한 레이어에서 접근해야 한다. 코드를 구조화하고, 불필요한 렌더를 줄이고, 측정 도구로 병목을 확인하는 과정을 반복하는 것이 핵심이다. 아래 항목은 우선적으로 점검해야 할 포인트들이다.

1. 컴포넌트 분리와 상태 최소화

상태를 필요 최소한의 컴포넌트로 좁히면 재렌더링 영향 범위를 줄일 수 있다. 상위 컴포넌트가 불필요하게 하위 컴포넌트를 다시 렌더링하지 않게 설계하는 것이 중요하다.

2. React.memo와 PureComponent 활용

함수형 컴포넌트에는 React.memo를 적용해 props 변경이 없을 때 렌더를 건너뛸 수 있다. 클래스형에서는 PureComponent를 사용해 얕은 비교로 불필요한 렌더를 막는다.

3. useMemo와 useCallback로 연산과 함수 재생성 제어

렌더마다 비용이 큰 계산이 반복된다면 useMemo로 결과를 캐시한다. 자식에 함수 prop을 전달할 때는 useCallback으로 함수 레퍼런스를 안정화해 불필요한 자식 재렌더를 방지한다.

4. 키(key)와 리스트 렌더링

리스트 렌더링 시 안정적인 key를 사용하면 Virtual DOM 비교가 효율적이다. 인덱스 사용은 재정렬이나 삽입이 잦은 경우 성능 문제를 일으킬 수 있다.

5. 레이지 로딩과 코드 분할

초기 로드에서 불필요한 코드나 컴포넌트를 로드하지 않도록 한다. React.lazy와 Suspense, 동적 import를 활용하면 초기 렌더 부담을 줄일 수 있다.

6. 리스트 가상화

수천 개 항목을 렌더링하는 경우 전체를 그리지 말고 가시 영역만 렌더링하는 기법을 적용한다. react-window, react-virtualized 같은 라이브러리를 사용하면 큰 성능 향상을 얻을 수 있다.

7. 이벤트 핸들러와 렌더링 분리

핸들러 내부에서 무거운 연산을 수행하지 않도록 하고, 필요한 경우 비동기 처리나 debouncing을 적용한다. 또한 핸들러를 렌더 내부에서 매번 새로 생성하지 않도록 주의한다.

코드 예제: 자주 쓰는 최적화 패턴

아래 예제는 React.memo와 useCallback을 적용한 간단한 패턴이다. JSX는 <와 > 문자를 변환해 표기한다.

const Item = React.memo(function Item({ text, onClick }) {
  return <div onClick={onClick}>{text}</div>;
});

function List({ items }) {
  const handleClick = React.useCallback((item) => {
    console.log(item);
  }, []);

  return <div>
    {items.map(i => (
      <Item key={i.id} text={i.text} onClick={() => handleClick(i)} />
    ))}
  </div>
}

위 코드에서 React.memo는 Item의 불필요한 재렌더를 막는다. 다만 onClick prop이 매번 새로 생성되면 효과가 사라진다. 이 문제는 handleClick을 useCallback으로 래핑하거나, 인라인 함수 사용을 줄이는 방식으로 해결할 수 있다.

성능 측정과 도구

최적화는 측정 기반으로 진행해야 한다. React Profiler로 어떤 컴포넌트가 자주 렌더되는지 확인한다. 브라우저의 Performance 탭으로 스택 트레이스를 분석하면 스타일, 레이아웃, 페인트 비용을 파악할 수 있다. 또한 Lighthouse로 전체적인 성능 지표를 점검하면 부족한 부분을 식별하기 쉽다.

실무 체크리스트

  • 불필요한 상위 상태는 없는가
  • 큰 리스트는 가상화되었는가
  • 함수와 객체 레퍼런스가 불필요하게 바뀌지는 않는가
  • 컴포넌트 분리가 명확한가
  • 프로파일링으로 병목을 확인했는가

마무리 요약

성능 최적화는 단순한 기술 적용이 아니라 구조적 접근이 필요하다. 먼저 react 렌더 사이클 이해를 통해 병목이 어디 있는지 찾는다. 그다음 성능 최적화 포인트 react에 따라 우선순위별로 개선을 진행한다. 마지막으로 virtual dom 렌더링 최적화와 측정 도구를 병행하면 안정적인 성능 개선을 달성할 수 있다.

react 렌더 사이클 이해 성능 최적화 포인트 react virtual dom 렌더링 최적화 react 성능 렌더링 최적화 React.memo useMemo useCallback