이 글은 누구를 위한 것인가
- React Native 앱을 운영 중인데 성능 문제가 있는 개발팀
- 새 아키텍처(New Architecture)가 무엇인지 정확히 알고 싶은 RN 개발자
- Expo SDK 52 이상으로 업그레이드를 앞둔 팀
들어가며
"React Native 앱이 네이티브보다 느려요." 몇 년 전까지만 해도 이 말이 당연하게 들렸다. JavaScript가 네이티브 코드로 변환되는 과정에서 병목이 생겼고, 복잡한 애니메이션이나 데이터 처리에서 버벅거림이 느껴졌다.
그 원인의 중심에 Bridge가 있었다. JavaScript와 네이티브 코드 사이의 비동기 통신 레이어인데, 모든 명령이 이 다리를 건너야 했고 직렬화/역직렬화 오버헤드가 발생했다.
React Native 팀은 이 Bridge를 없애기로 했다. 3년에 걸친 재설계의 결과가 **새 아키텍처(New Architecture)**다. React Native 0.76부터 기본으로 활성화됐다.
1. 기존 Bridge 아키텍처의 문제
Bridge 방식을 이해해야 새 아키텍처의 가치를 알 수 있다.
[기존 Bridge 아키텍처]
JavaScript 스레드 Bridge 네이티브 스레드
│ │ │
setState() ──JSON직렬화──▶ 네이티브 UI 업데이트
│ ◀─JSON역직렬화── 이벤트 콜백
│ │ │
비동기 처리 (큐에 쌓임)
문제 1: 비동기 특성 Bridge는 비동기 큐 방식이다. JavaScript에서 UI 업데이트를 요청하면, 즉시 처리되지 않고 큐에 쌓인다. 이 지연이 부드러운 60fps 애니메이션을 방해한다.
문제 2: 직렬화 오버헤드 JavaScript 객체를 네이티브로 전달하려면 JSON으로 변환해야 하고, 네이티브에서 돌아올 때도 역변환이 필요하다. 대용량 데이터 처리 시 이 오버헤드가 크다.
문제 3: 모든 네이티브 모듈을 미리 초기화 앱 시작 시 사용 여부와 관계없이 모든 네이티브 모듈을 메모리에 올린다. 앱 시작 시간이 느려지는 원인 중 하나다.
2. 새 아키텍처 3가지 핵심 변화
JSI (JavaScript Interface)
JSI는 Bridge를 제거하고 JavaScript가 C++ 코드를 직접 호출하게 한다.
[새 아키텍처 - JSI]
JavaScript ──C++ 직접 호출──▶ 네이티브
│ ◀─동기 리턴── │
│
동기 호출 가능! 직렬화 없음!
JavaScript Object를 JSON으로 변환할 필요가 없다. JavaScript와 C++이 같은 메모리 공간의 객체를 공유한다. 이를 통해 동기 호출도 가능해졌고, 오버헤드가 대폭 줄었다.
Fabric Renderer
Fabric은 UI 렌더링 레이어의 완전한 재작성이다. React의 동시 모드(Concurrent Mode) 기능을 네이티브 UI에 적용할 수 있게 된다.
[기존] JavaScript에서 UI 업데이트 → 메인 스레드 블로킹 가능
[Fabric]
- UI 계산을 백그라운드에서 처리
- 우선순위 높은 업데이트를 인터럽트 가능
- React Suspense와 자연스럽게 연동
실용적인 효과: 복잡한 목록 스크롤 중에도 사용자 입력에 즉시 반응하는 UI가 가능해진다.
TurboModules
기존에는 모든 네이티브 모듈이 앱 시작 시 초기화됐다. TurboModules는 **필요할 때 로드(Lazy Loading)**한다.
[기존] 앱 시작 → 카메라 모듈 로드 → 블루투스 모듈 로드 → ... → 100개 모듈 전부 로드
[TurboModules] 앱 시작 → 실제로 사용될 때만 해당 모듈 로드
네이티브 모듈이 많은 앱에서 앱 시작 시간이 크게 개선된다.
3. 새 아키텍처에서 성능이 얼마나 개선되는가
Meta(Facebook)가 실제 앱에서 측정한 수치:
| 지표 | 기존 | 새 아키텍처 | 개선율 |
|---|---|---|---|
| 앱 시작 시간 | 2.1초 | 1.6초 | 24% 개선 |
| 목록 스크롤 드롭 프레임 | 12% | 3% | 75% 감소 |
| 메모리 사용량 | 기준 | -8% | 소폭 감소 |
| JS-네이티브 호출 지연 | ~15ms | <1ms | 15배 향상 |
4. 기존 앱에서 새 아키텍처로 마이그레이션
Expo 사용 중인 경우 (가장 간단)
// app.json
{
"expo": {
"newArchEnabled": true
}
}
Expo SDK 52 이상에서는 이 설정 하나로 새 아키텍처가 활성화된다. Expo Go 대신 개발 빌드를 사용해야 한다.
React Native CLI 사용 중인 경우
// android/gradle.properties
newArchEnabled=true
# ios/Podfile
ENV['RCT_NEW_ARCH_ENABLED'] = '1'
마이그레이션 체크리스트
□ React Native 0.73 이상으로 업그레이드
□ 사용 중인 서드파티 라이브러리 호환성 확인
□ 네이티브 모듈 직접 작성한 경우 TurboModule API로 업데이트
□ 스테이징 환경에서 충분한 테스트
□ Flipper 2.0으로 업그레이드 (디버깅 도구)
5. 라이브러리 호환성 문제 대처
새 아키텍처 전환의 가장 현실적인 장벽은 서드파티 라이브러리 호환성이다.
확인 방법: reactnative.directory에서 라이브러리를 검색하면 새 아키텍처 지원 여부를 확인할 수 있다.
주요 라이브러리 지원 현황 (2026년 1분기)
| 라이브러리 | 새 아키텍처 지원 |
|---|---|
| react-navigation | ✅ 완전 지원 |
| react-native-gesture-handler | ✅ 완전 지원 |
| react-native-reanimated | ✅ 완전 지원 |
| react-native-screens | ✅ 완전 지원 |
| react-native-camera | ⚠️ 부분 지원 |
| react-native-maps | ✅ 완전 지원 |
미지원 라이브러리가 있다면 세 가지 선택지가 있다:
- 대안 라이브러리로 교체
- 해당 라이브러리만 Bridge 레거시 모드로 유지 (일시적)
- 라이브러리를 직접 포크해서 새 아키텍처 지원 추가
6. 새 아키텍처와 Expo
Expo를 사용하는 팀에게 좋은 소식이 있다. Expo SDK 52부터 새 아키텍처가 기본값으로 전환됐다. EAS Build를 사용하면 별도 네이티브 설정 없이도 새 아키텍처 앱을 빌드할 수 있다.
# EAS Build로 새 아키텍처 앱 빌드
npx expo install expo-dev-client
eas build --platform all
Expo Go는 새 아키텍처를 지원하지 않으므로, 개발 과정에서 Expo Dev Client(개발 빌드)를 사용해야 한다. 초기 설정이 약간 번거롭지만, 한번 설정하면 개발 경험은 거의 동일하다.
맺으며
React Native 새 아키텍처는 "단순 성능 개선"을 넘어 "근본적인 구조 개선"이다. Bridge라는 오래된 기술 부채를 해소하고, React의 최신 기능(Concurrent Mode, Suspense)을 네이티브에서 제대로 활용할 수 있게 됐다.
마이그레이션이 걱정된다면 Expo를 사용 중인 팀은 SDK 52로 업그레이드하는 것이 가장 쉬운 시작점이다. 라이브러리 호환성을 먼저 확인하고, 테스트 커버리지가 있다면 두려워할 이유가 없다. 새 아키텍처는 이미 Meta의 Facebook, Instagram 앱에서 수억 명이 매일 쓰고 있다.