Skip to content

ADR-22: React Compiler 도입 ​

🇺🇸 English Version

날짜작성자리포지토리
2026-01-19@KubrickCodeweb

배경 ​

수동 메모이제이션 부담 ​

웹 애플리케이션 전반에 상당한 수동 메모이제이션 오버헤드 누적:

  • 27개 파일에 명시적 useMemo 및 useCallback 호출 존재
  • 메모이제이션 필요 여부 판단에 대한 개발자 인지 부하
  • 과도한 메모이제이션(불필요한 복잡성) 또는 메모이제이션 부족(성능 문제) 위험
  • 메모이제이션 의존성이 있는 컴포넌트 리팩토링 시 유지보수 부담

React Compiler 기회 ​

ADR-02: Next.js 16 + React 19 선택에서 채택한 React 19에 React Compiler(이전 React Forget) 포함. 컴파일러가 빌드 타임에 메모이제이션 최적화 자동 적용, 대부분의 경우 수동 useMemo, useCallback, React.memo 불필요.

ADR-02 성능 전망: "React Compiler 자동 메모이제이션 (리렌더 25-40% 감소)"

배포 후 발견된 문제 ​

React Compiler 활성화 후 TanStack Virtual 사용 컴포넌트 2개에서 동작 이상 발생:

  • test-list.tsx - 가상화된 테스트 결과 목록
  • tree-view.tsx - 가상화된 파일 트리 네비게이션

근본 원인: React Compiler의 공격적 메모이제이션이 virtualizer.getVirtualItems() 결과 캐싱. 가상화 참조가 변경되지 않아 가상 아이템 미갱신, 빈 목록 또는 오래된 목록 표시.

React Compiler와 TanStack Virtual의 measureElement 및 ResizeObserver 사용 ref 기반 측정 패턴 간 알려진 호환성 문제.

결정 ​

호환되지 않는 서드파티 라이브러리 패턴용 "use no memo" 이스케이프 해치와 함께 React Compiler 전역 도입.

핵심 원칙 ​

  1. 컴파일러 우선: 모든 컴포넌트에 기본적으로 React Compiler 활성화
  2. 명시적 제외: 문서화된 비호환성에 대해서만 "use no memo" 지시어 사용
  3. 수동 메모이제이션 제거: 컴파일러 최적화 컴포넌트에서 useMemo/useCallback 삭제
  4. 예외 문서화: 제외 컴포넌트 목록 및 근거 유지

설정 ​

typescript
// next.config.ts
const nextConfig = {
  reactCompiler: true,
  // ...
};

의존성 ​

json
{
  "devDependencies": {
    "babel-plugin-react-compiler": "1.0.0"
  }
}

이스케이프 해치 사용법 ​

tsx
"use no memo";

export function VirtualizedList() {
  // React Compiler 최적화에서 제외
  const virtualizer = useVirtualizer({ ... });
  return ...;
}

검토한 옵션 ​

옵션 A: 이스케이프 해치를 통한 전체 React Compiler 도입 (선택) ​

reactCompiler: true 전역 활성화, 수동 메모이제이션 제거, 비호환성에 "use no memo" 적용.

장점단점
코드 단순화 (27개 파일 정리)라이브러리 호환성 오버헤드
일관된 최적화 전략디버깅 시 컴파일러 이해 필요
미래 지향적, React 방향과 일치이스케이프 해치 남용 위험
개발자 메모이제이션 결정 불필요

옵션 B: 수동 메모이제이션 유지 ​

React Compiler 미활성화, 기존 패턴 유지.

장점단점
호환성 위험 없음지속적인 인지 부담
익숙한 패턴일관성 없는 적용
React 생태계 방향과 배치

기각: ADR-02에서 컴파일러 이점을 위해 React 19 명시적 채택.

옵션 C: 선택적/점진적 도입 ​

"use memo" 지시어로 옵트인 모드에서 React Compiler 활성화.

장점단점
안전한 롤아웃노력 배가 (수동 결정 여전히 필요)
컴포넌트별 검증부분적 이점, 일관성 없는 상태

기각: 이스케이프 해치 패턴이 더 적은 오버헤드로 안전한 롤아웃 달성.

결과 ​

긍정적 ​

영역이점
코드 단순화27개 파일에서 수동 메모이제이션 제거
성능 일관성컴파일러가 정적 분석으로 최적 메모이제이션 적용
개발자 경험언제 메모이제이션할지 판단하는 정신적 오버헤드 제거
생태계 정렬향후 React 최적화를 위한 코드베이스 포지셔닝

부정적 ​

영역트레이드오프완화 방안
라이브러리 호환성TanStack Virtual에 "use no memo" 필요컴포넌트 파일에 문서화
이스케이프 해치 거버넌스지시어 남용 위험근거 필수 코드 리뷰 정책
디버깅 복잡성컴파일러 변환 이해 필요React DevTools Compiler 배지

영향받는 컴포넌트 ​

컴포넌트문제해결책상태
test-list.tsxTanStack Virtual ref 캐싱"use no memo"TanStack 수정 시까지 임시
tree-view.tsxTanStack Virtual ref 캐싱"use no memo"TanStack 수정 시까지 임시

코딩 가이드라인 ​

CLAUDE.md에 추가:

markdown
## React Compiler

React Compiler 활성화 (`next.config.ts`: `reactCompiler: true`)

### 금지

- `useMemo`, `useCallback`, `React.memo` **절대 사용 금지**
- React Compiler가 빌드 타임에 자동으로 메모이제이션 처리

### 이스케이프 해치

컴파일러가 문제를 일으키는 경우에만 `"use no memo"` 지시어 사용

참조 ​

Open-source test coverage insights