React App 리렌더링이 너무 많이 발생함: 숨겨진 성능 버그와 올바른 해결책
Source: Dev.to


React 애플리케이션이 처음에는 빠르게 느껴지지만 기능이 늘어날수록 느려진다면, 과도한 재렌더링이 실제 문제인 경우가 많습니다. 이 문제는 흔하고, 초기에 눈치채기 어렵으며, 자주 오해됩니다. 많은 개발자들이 메모이제이션을 곳곳에 적용하려고 시도하지만, 오히려 상황을 악화시키는 경우가 많습니다.
개발자들이 흔히 검색하는 증상
다음과 같은 경우 이 문제에 직면했을 수 있습니다:
- props가 변하지 않아도 컴포넌트가 다시 렌더링됨
- 하나의 입력에 타이핑하면 전체 페이지가 다시 렌더링됨
- 상태가 증가함에 따라 성능이 저하됨
- React DevTools에 빈번한 렌더링이 표시됨
memo와useCallback이 도움이 되지 않는 것처럼 보임
이는 React 버그가 아니라 설계상의 실수입니다.
React가 과도하게 다시 렌더링되는 진짜 이유
React는 값이 아니라 레퍼런스가 변경될 때 상태(state)나 props가 다시 렌더링됩니다. 대부분의 성능 문제는 다음에서 비롯됩니다:
- 컴포넌트 트리 상단에 상태가 너무 높게 저장됨
- 매 렌더링마다 객체와 함수가 재생성됨
- 의존성 배열이 잘못 지정됨
- 컨텍스트를 전역 스토어처럼 사용함
가장 흔한 실수 (실제 앱에서 발견됨)
문제 코드
function App() {
const [user, setUser] = useState({ name: 'Alex' });
return ;
}
user.name이 변하지 않더라도, 업데이트 시 객체 참조가 바뀌어 리렌더가 발생합니다.
메모이제이션만으로는 이 문제가 해결되지 않는 이유
많은 개발자들이 다음과 같이 추가합니다:
export default React.memo(Profile);
이 경우 아무 효과도 없을 때가 많습니다. 프롭 참조가 여전히 변경되기 때문입니다. 아키텍처가 잘못된 경우 메모이제이션은 해결책이 될 수 없습니다.
Step 1 – 상태를 사용되는 곳에 가깝게 이동하기
올바른 수정
function Profile() {
const [name, setName] = useState('Alex');
return { name };
}
상태를 사용되는 위치에 두면 메모이제이션 없이도 자동으로 리렌더링이 감소합니다.
단계 2 – 객체와 함수를 인라인으로 생성하지 않기
문제
handleClick()} />
각 렌더링마다 새로운 참조가 생성됩니다.
해결 방법
const style = { marginTop: 10 };
const onClick = useCallback(() => {
handleClick();
}, []);
이제 React가 렌더링을 적절히 최적화할 수 있습니다.
Step 3 – Context는 상태 관리자가 아니다
Using Context for frequently changing data causes mass re‑renders.
잘못된 사용 사례
- Authentication state
- Theme toggles
- Live counters
- User typing state
Context re‑renders all consumers when the value changes. Use local state or a dedicated state manager instead.
Step 4 – 최적화 전에 측정하기
절대 추측하지 마세요. React DevTools를 사용하세요:
- “Highlight updates” 활성화
- 어떤 컴포넌트가 다시 렌더링되는지 확인
- 왜 다시 렌더링되는지 추적
다시 렌더링이 보이지 않으면 최적화하지 마세요.
Step 5 – When Memoization Actually Makes Sense
- Props가 안정적이다
- 컴포넌트 렌더링 비용이 높다
- 재렌더링 빈도가 높다
메모이제이션을 과도하게 사용하면 복잡성과 버그가 증가합니다.
실제 애플리케이션에서 이것이 중요한 이유
성능 문제는 단순히 사용자 경험(UX)에만 영향을 미치는 것이 아니라 신뢰에도 영향을 미칩니다. 대시보드이든 SaaS 제품이든, 혹은 Shopperdot과 같은 성능 중심의 온라인 플랫폼과 같은 맞춤형 전자상거래 경험이든, 불필요한 재렌더링은 사용자 참여를 조용히 해칩니다. 빠른 인터페이스는 신뢰감을 주고, 느린 인터페이스는 깨진 느낌을 줍니다.
최종 생각
React은 기본적으로 빠릅니다. 앱이 느려질 때 원인은 거의 항상:
- 상태 배치가 부적절함
- 불안정한 참조
- Context 오용
- 무분별한 메모이제이션
먼저 아키텍처를 수정하세요. 두 번째로 최적화하세요. 이것이 React 앱이 확장하면서도 빠르게 유지되는 방법입니다.