본문 바로가기
3주차

🚀리렌더링 지옥 탈출

by mmhs 2025. 5. 2.

 

안녕하세요 웹파트 YB 문혜성입니다!

 

"성능을 올려보겠다고 useMemo랑 useCallback 막 썼는데, 오히려 코드가 더 꼬이고 느려지더라고요." 이런 말… 들어보신 적 있으신가요?

 

최근 세미나에서 useMemo를 포함한 다양한 메모제이션 훅들을 배웠습니다. 당시에는 "불필요한 리렌더링을 막는다"는 설명을 듣고 어느 정도 납득했지만, 실제 코드에 적용해보니 의문이 들기 시작했어요.

 

  • 도대체 언제 써야 정말 효과적인 걸까?
  • useMemo나 useCallback을 쓰면 성능이 눈에 띄게 좋아지는 걸까?
  • 아니면 그냥 코드만 복잡해지고, 오히려 성능이 떨어질 수도 있는 걸까?

 

그래서 이번 글에서는 각 메모이제이션 도구들을 언제, 왜 써야 하는지를 정리해보려고 해요. React.memo, useMemo, useCallback의 실제 사용 사례와 주의할 점까지 함께 다루니, 한 번쯤 헷갈렸던 분들이라면 꼭 읽어보시면 좋을 것 같아요.😊

 


🔍 리렌더링이 일어나는 이유

 

React 컴포넌트는 이런 상황에서 리렌더링돼요!

  1. state가 바뀔 때
  2. 부모 컴포넌트가 리렌더링될 때
  3. props가 바뀔 때
  4. Context 값이 바뀔 때

그런데 꼭 필요한 리렌더링도 있지만, 안 해도 되는 리렌더링이 자꾸 일어나면 앱이 느려지기도 하고 디버깅이 어려워져요.🤯

그래서!!  "불필요한 리렌더링을 막자"는 이야기가 나오는 거죠.

 

 


 

🛠️ 메모이제이션 3형제: 언제, 왜 쓰는지

1. React.memo

React.memo는 컴포넌트를 감싸서, props가 안 바뀌면 리렌더링을 건너뛰게 해줘요.

const Child = React.memo(({ value }) => {
  console.log("Child 렌더링");
  return <div>{value}</div>;
});

 

👉 이런 상황에서 좋아요

  • 부모 컴포넌트가 자주 바뀌는데, 자식 컴포넌트는 props가 거의 안 바뀔 때

❗ 주의할 점

  • props가 객체나 함수면 매번 새롭게 생성되기 때문에 효과가 없을 수도 있어요 → useMemo나 useCallback이랑 같이 써줘야 해요

 

2. useMemo

useMemo는 계산이 오래 걸리는 연산을 캐싱해서, 값이 바뀌지 않는 이상 다시 계산하지 않도록 해줘요.

const expensiveValue = useMemo(() => {
  return heavyComputation(data);
}, [data]);

 

👉 이런 상황에서 좋아요

  • 렌더링할 때 무거운 계산을 반복해서 해야 할 때
  • 복잡한 객체를 props로 넘기는데 참조가 바뀌면 불필요하게 리렌더링 되는 게 싫을 때

❗ 이런 경우는 굳이 안 써도 돼요

  • 계산이 가볍거나, 렌더링 자체가 자주 안 일어나는 경우엔 메모이제이션 비용이 더 클 수 있어요

 

3. useCallback

useCallback은 함수를 매번 새로 만들지 않고, 의존성이 안 바뀌면 기존 함수를 재사용할 수 있게 해줘요.

const handleClick = useCallback(() => {
  doSomething(id);
}, [id]);

 

👉 이런 상황에서 좋아요

  • 함수를 자식 컴포넌트에 props로 넘기는데, 매번 새 함수가 생겨서 리렌더링되는 걸 막고 싶을 때

❗ 이건 좀 주의하세요

  • useCallback도 결국 메모리를 쓰는 거라, 너무 남발하면 오히려 손해일 수 있어요

 


📋 요약: 언제 쓰고 언제 안 써야 할까?

 

상황 추천 도구 이유
부모가 자주 리렌더링 + 자식 props는 그대로 React.memo 불필요한 렌더링 방지
연산이 무겁고 반복된다 useMemo 계산 캐싱으로 속도 개선
함수 props 전달+ 참조 유지가 필요 useCallback 함수 재생성 방지
렌더링 거의 안 일어나거나 연산 가벼움 ❌안 써도 됨 오히려 복잡해지고 느려질 수도 있음

 

 


🔍 진짜 효과 있는지 DevTools로 확인해보세요

React DevTools에 있는 Profiler 탭을 사용하면 어떤 컴포넌트가 몇 번, 왜 렌더링됐는지를 확인할 수 있어요. 그냥 "느려진 것 같다"고 느끼기보단, 직접 눈으로 보고 최적화 포인트를 잡는 게 훨씬 확실합니다.

 

React Profiler 탭 예시


마무리하며: 도구보다 판단이 먼저!

 

세미나에서 useMemo랑 useCallback을 최적화 도구로 배운 이후에 실제로 사용해보니, 생각보다 신중하게 접근해야겠다는 걸 느꼈어요.

꼭 써야 하는 순간에만 적절하게 사용하는 게 가장 중요하더라고요. 성능 때문에 썼는데 오히려 복잡해지고 느려지면 본전도 못 찾는 느낌이니까요.😓

그래서 앞으로는 "측정 → 판단 → 정밀 적용"이라는 흐름을 기억하면서, 더 똑똑하게 React를 써보려고 해요. 이 글이 같은 고민을 가진 분들께 조금이나마 도움이 되었으면 좋겠습니다 👍

 

 

출처: React 렌더링 개념도 - Bing 이미지, https://www.geeksforgeeks.org/optimizing-performance-with-usememo-and-usecallback-hooks/, FreeCodeCamp - React Memoization 완전정복, https://legacy.reactjs.org/blog/2018/09/10/introducing-the-react-profiler.html