React Forget: React Compiler가 가져올 메모이제이션 지옥에서의 해방
리액트 개발자라면 누구나 한 번쯤 useMemo, useCallback, 그리고 React.memo 사이에서 고민하며 “이게 정말 최적화가 되는 걸까?” 혹은 “의존성 배열(Dependency Array)에 뭘 넣어야 하지?”라는 질문을 던져봤을 것입니다.
이런 수동 최적화의 고통을 끝내기 위해 등장한 프로젝트가 바로 **React Forget(React Compiler)**입니다.
1. 수동 최적화의 한계
기존 리액트의 렌더링 모델은 컴포넌트의 상태가 변하면 하위 트리 전체를 다시 그리는 방식입니다. 이를 방지하기 위해 우리는 개발자가 직접 메모이제이션을 수행해왔습니다.
- 가독성 저하: 비즈니스 로직보다 최적화 코드가 더 길어지는 현상.
- 실수 유발: 의존성 배열을 잘못 관리하면 버그가 발생하거나 최적화가 무용지물이 됨.
- 멘탈 모델의 복잡성: 언제 메모이제이션을 써야 할지 판단하는 기준이 모호함.
2. React Compiler란 무엇인가?
React Compiler는 빌드 타임에 리액트 코드를 분석하여, 값이 변경되지 않았을 때 재렌더링을 방지하는 코드를 자동으로 삽입하는 도구입니다.
핵심은 **“컴포넌트의 결과값이 입력값(Props, State)에 의존한다”**는 것을 컴파일러가 이해하고, 변경이 없을 때 이전 결과를 재사용하도록 코드를 변환하는 것입니다.
3. 무엇이 바뀌나? (Before vs After)
우리가 작성하는 코드는 훨씬 단순해집니다.
// Before: 수동으로 메모이제이션 처리
const memoizedValue = useMemo(() => {
return computeExpensiveValue(a, b);
}, [a, b]);
const handleClick = useCallback(() => {
console.log(a);
}, [a]);
// After: 그냥 일반 함수와 변수처럼 작성
const value = computeExpensiveValue(a, b);
const handleClick = () => {
console.log(a);
};
컴파일러는 위 코드를 보고 a와 b가 변하지 않았다면 value와 handleClick을 새로 만들지 않도록 로우 레벨에서 코드를 재구성합니다.
4. 도입 시 주의사항
React Compiler가 마법처럼 모든 것을 해결해주지만, 지켜야 할 규칙은 더욱 엄격해집니다.
- Strict Mode 준수: 순수 함수(Pure Function) 규칙을 엄격히 지켜야 합니다. 렌더링 도중 외부 변수를 직접 수정하는 등의 부수 효과(Side Effect)는 컴파일러를 혼란스럽게 만듭니다.
- React Rules: Hook의 규칙을 정확히 따라야 컴파일러가 안전하게 최적화를 적용할 수 있습니다.
- 점진적 도입: 전체 프로젝트를 한 번에 바꾸기보다, 특정 컴포넌트 단위로 적용하며 성능 변화를 관찰하는 것이 좋습니다.
5. 마치며: ‘리액트 방식’의 완성
React Forget이라는 이름은 “최적화에 대해 잊어버려라(Forget)“는 의미를 담고 있습니다. 개발자는 다시 UI의 구조와 비즈니스 로직에만 집중하고, 기계적인 최적화는 컴파일러에게 맡기는 시대가 된 것이죠.
이제 복잡한 의존성 배열과의 싸움을 멈추고, 더 직관적인 리액트 개발을 준비해 보세요.