React · 2026-04-07

React 성능 저하 유발 안티패턴 정리

React 애플리케이션에서 자주 마주치는 렌더링 관련 안티패턴을 정리한 글. 각 항목의 원인과 개선 방법을 사례 중심으로 설명한 기술 참고자료.

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

들어가며

React를 쓰다 보면 기능은 동작하지만 성능이 느려지는 경우가 있다. 문제의 상당수는 설계나 코드 패턴에서 기인한다. 이 글은 초보자도 이해하기 쉽도록 react 안티패턴 목록을 중심으로 원인과 해결책을 제시한다. 또한 리액트 성능 저하 원인을 실제 사례로 연결한다.

1. 불필요한 재렌더링을 초래하는 패턴

1-1. 부모가 자식을 자주 다시 렌더링하는 경우

상태가 부모에만 있고 변경될 때마다 자식 전체가 재렌더링되면 비용이 커진다. 특히 자식이 컴포넌트 트리 깊숙이 있을 때 영향이 크다. 이를 해결하려면 컴포넌트 분리와 메모이제이션을 고려한다.

1-2. 해결책 예시

const Parent = () => {
  const [count, setCount] = useState(0);
  // 자식이 불필요하게 재렌더링되는 예시
  return (
    <div>
      <button onClick={() => setCount(c => c + 1)}>증가</button>
      <Child />
    </div>
  );
}

// 개선: Child를 React.memo로 감싸고 필요한 props만 전달
const Child = React.memo(() => {
  return <div>자식 컴포넌트</div>
});

2. 불변성 깨기 또는 참조 변화가 잦은 상태

객체나 배열 상태를 직접 수정하면 예측하기 어려운 렌더링이 발생한다. 반대로 매 렌더마다 새로운 객체를 만들어 prop으로 넘기면 자식은 불필요하게 업데이트된다. 이 부분은 나쁜 렌더링 패턴 react의 전형이다.

2-1. 해결 기준

  • 상태는 불변성 유지
  • 필요 시 useMemo로 계산 결과 캐시
  • 빈번한 참조 생성은 피함

3. 화살표 함수·인라인 객체를 props로 넘기는 경우

렌더링마다 새 함수와 객체가 생성되면 자식 비교에서 변화로 판단한다. 이로 인해 React.memo를 써도 소용없어진다.

3-1. 개선 예시

function List({ items, onSelect }) {
  return <ul>{items.map(i => <li key={i.id} onClick={() => onSelect(i)}>{i.name}</li>)}</ul>
}

// 개선: onSelect를 부모에서 useCallback으로 고정
const Parent = () => {
  const onSelect = useCallback(item => { /* 처리 */ }, []);
  return <List items={items} onSelect={onSelect} />
};

4. 무거운 계산을 매 렌더마다 수행

렌더 사이클에서 복잡한 연산을 직접 실행하면 프레임 드랍이 발생한다. 이를 방지하려면 useMemo 또는 웹 워커로 오프로드한다.

4-1. 개선 예시

const result = useMemo(() => expensiveCalculation(data), [data]);

5. 부적절한 키 사용과 리스트 렌더링

리스트 렌더링에서 인덱스를 키로 쓰면 항목 삽입·삭제 시 재사용이 깨진다. 키는 고유하고 안정적인 값을 사용해야 한다.

6. 잘못된 useEffect 의존성 관리

의존성 배열을 빼먹거나 과하게 넣으면 무한 루프나 불필요한 사이드 이펙트가 발생한다. 사이드 이펙트는 렌더 성능에 직결된다. 의존성은 정확히 명시하고, 필요하면 콜백을 분리한다.

7. 너무 많은 상태 분리 또는 단일 거대한 상태

모든 데이터를 하나의 상태로 관리하면 작은 변경에도 전체가 재계산된다. 반대로 상태를 너무 나누면 관리 복잡성이 커진다. 균형 있게 설계하고 선택적 렌더링을 적용한다.

8. 대량 리스트에 대한 가상화 미적용

항목이 많은 리스트는 화면에 보이는 부분만 렌더링해야 한다. react-window, react-virtualized 같은 라이브러리를 도입하면 메모리와 렌더 비용을 크게 줄일 수 있다.

9. 요약 및 체크리스트

  • 컴포넌트 경계 명확화 및 메모이제이션 적용
  • 불변성 유지와 참조 생성 최소화
  • 함수·객체 props는 고정하거나 useCallback/useMemo 사용
  • 무거운 연산은 캐시 또는 워커로 분리
  • 리스트 키는 안정적인 값 사용, 대량 리스트는 가상화
  • useEffect 의존성 정확히 관리

위 항목들은 흔한 react 안티패턴 목록과 연결된다. 각 항목을 점검하면 리액트 성능 저하 원인을 빠르게 좁힐 수 있다. 정리하면, 작은 설계 실수가 전체 성능에 큰 영향을 준다. 따라서 의식적으로 패턴을 점검하고 필요한 도구를 활용하면 안정적인 성능을 유지할 수 있다.

react 안티패턴 목록 리액트 성능 저하 원인 나쁜 렌더링 패턴 react React 최적화 렌더링 성능 useMemo 사용법 useCallback 최적화 리액트 가상화