HW부터 React Native까지 — 모바일 앱 실행 구조
한 문장 요약
React Native 코드 → Metro 번들 → Hermes 실행 → JSI/TurboModules → Fabric/UIManager → 네이티브 UI → GPU → 화면 픽셀
전체 실행 스택
┌─────────────────────────────────────────────────────┐
│ React Native 소스 코드 (JavaScript / TypeScript) │
│ │
│ function App() { │
│ return <View><Text>Hello</Text></View>; │
│ } │
└──────────────────────┬──────────────────────────────┘
│ Metro 번들 생성
▼
┌─────────────────────────────────────────────────────┐
│ Metro Bundler │
│ │
│ - JS 파일 번들링 (의존성 그래프를 하나의 번들로) │
│ - JSX 변환 (Babel): <View> → React.createElement() │
│ - TypeScript 트랜스파일 │
│ - 개발 시 Fast Refresh용 소스맵/모듈 그래프 관리 │
│ → index.bundle / RAM bundle 등 결과물 생성 │
└──────────────────────┬──────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────┐
│ JS 엔진 선택 (플랫폼별) │
│ │
│ ┌───────────────────┬───────────────────────────┐ │
│ │ Hermes (기본값) │ V8 / JSC (대안) │ │
│ │ (Meta 개발) │ │ │
│ │ │ │ │
│ │ Ahead-of-time │ 런타임 파싱/JIT │ │
│ │ bytecode 생성 │ (엔진별 방식 상이) │ │
│ │ │ │ │
│ │ 장점: │ 장점: │ │
│ │ - 빠른 시작 │ - 실행 중 최적화 │ │
│ │ - 낮은 메모리 │ - 복잡한 연산에 유리 │ │
│ │ - 앱 번들에 포함 │ │ │
│ └───────────────────┴───────────────────────────┘ │
│ │
│ Hermes 바이트코드 (.hbc): │
│ - JS 번들 → Hermes 바이트코드로 미리 변환 │
│ - 앱 패키지에 함께 포함되어 배포 │
│ - 앱 시작 시 바로 로드 → parse/JIT 비용 감소 │
└──────────────────────┬──────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────┐
│ React Runtime + JSI │
│ │
│ ┌──────────────────────────────────────────────┐ │
│ │ 구 아키텍처 (Bridge 방식, 레거시) │ │
│ │ │ │
│ │ JS 스레드 Native 스레드 │ │
│ │ ┌──────────┐ JSON 직렬화 ┌──────────────┐ │ │
│ │ │ JS 코드 │ ────────────> │ Native 모듈 │ │ │
│ │ └──────────┘ 비동기 큐 └──────────────┘ │ │
│ │ │ │
│ │ 단점: JSON 직렬화 오버헤드, 비동기 지연 │ │
│ └──────────────────────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────────┐ │
│ │ 신 아키텍처 (JSI + TurboModules + Fabric) │ │
│ │ │ │
│ │ JS 런타임 │ │
│ │ ┌──────────┐ C++ HostObject/HostFunction │ │
│ │ │ JS 코드 │ ─────────────────────────────> │ │
│ │ └──────────┘ 동기 호출 가능 │ │
│ │ ┌──────────────────────────┐ │ │
│ │ │ TurboModule (Native) │ │ │
│ │ │ C++ HostObject │ │ │
│ │ └──────────────────────────┘ │ │
│ │ │ │
│ │ 장점: 동기 호출, JSON 직렬화 불필요 │ │
│ └──────────────────────────────────────────────┘ │
└──────────────────────┬──────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────┐
│ React Reconciler + Fabric │
│ │
│ <View><Text>Hello</Text></View> │
│ ↓ │
│ Virtual DOM (React Fiber 트리) │
│ ↓ 변경 감지 (diffing) │
│ Shadow Tree (Fabric의 C++ UI 트리) │
│ ↓ │
│ Yoga 레이아웃 엔진 (Flexbox → 픽셀 좌표 계산) │
│ ↓ │
│ Mounting Layer → 실제 UIView / android.view.View │
└──────────────────────┬──────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────┐
│ 네이티브 UI 렌더러 │
│ │
│ ┌──────────────────┬──────────────────────────┐ │
│ │ iOS │ Android │ │
│ │ │ │ │
│ │ UIKit │ View (Android) │ │
│ │ ┌────────────┐ │ ┌──────────────────┐ │ │
│ │ │ UIView │ │ │ android.view.View│ │ │
│ │ │ UILabel │ │ │ TextView │ │ │
│ │ │ UIButton │ │ │ Button │ │ │
│ │ └────────────┘ │ └──────────────────┘ │ │
│ │ Objective-C/ │ Kotlin/Java │ │
│ │ Swift │ │ │
│ └──────────────────┴──────────────────────────┘ │
│ │
│ Fabric (신 렌더러): │
│ - C++ 공통 렌더 트리 사용 │
│ - Commit/Mount 단계를 플랫폼별 UI에 반영 │
│ - 브릿지 병목 감소 → 대규모 리스트/애니메이션 개선 │
└──────────────────────┬──────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────┐
│ OS 그래픽 시스템 │
│ │
│ iOS: Core Animation → Metal (GPU API) │
│ Android: RenderThread → Vulkan / OpenGL ES │
│ │
│ 렌더링 파이프라인: │
│ UI 트리 → 레이어 합성(Compositing) → 렌더 커맨드 │
└──────────────────────┬──────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────┐
│ GPU │
│ │
│ Vertex Shader → Rasterization → Fragment Shader │
│ → 프레임 버퍼 → 디스플레이 (60fps / 120fps) │
│ │
│ 60fps = 16.67ms 마다 새 프레임 렌더링 │
│ JS나 UI 스레드가 예산을 넘기면 프레임 드롭 발생 │
└──────────────────────┬──────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────┐
│ CPU / 트랜지스터 │
│ 모바일 SoC (System on Chip): │
│ CPU + GPU + NPU + 모뎀 + 메모리가 하나의 칩에 │
│ Apple A-series / Snapdragon 계열 │
└─────────────────────────────────────────────────────┘
스레드 구조 (실행 중)
┌─────────────────────────────────────────────────────┐
│ React Native 앱의 스레드 구성 │
│ │
│ ┌────────────────────────────────────────────┐ │
│ │ JS 스레드 │ │
│ │ - Hermes/V8/JSC 실행 │ │
│ │ - React Reconciler (Virtual DOM diffing) │ │
│ │ - 비즈니스 로직 │ │
│ │ - 단일 스레드 → CPU 집약 작업 시 UI 끊김 │ │
│ └────────────────────────────────────────────┘ │
│ │
│ ┌────────────────────────────────────────────┐ │
│ │ Shadow / Render 스레드 │ │
│ │ - Fabric Shadow Tree 관리 │ │
│ │ - Yoga 레이아웃 계산 │ │
│ └────────────────────────────────────────────┘ │
│ │
│ ┌────────────────────────────────────────────┐ │
│ │ 메인(UI) 스레드 │ │
│ │ - 네이티브 뷰 업데이트 │ │
│ │ - 터치 이벤트 수신 │ │
│ │ - 절대 블로킹 금지 (ANR / 앱 멈춤) │ │
│ └────────────────────────────────────────────┘ │
│ │
│ ┌────────────────────────────────────────────┐ │
│ │ Native 모듈 / Background 스레드 │ │
│ │ - 카메라, 파일, DB, 네트워크 등 작업 │ │
│ └────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────┘
React Native vs 네이티브 앱 비교
┌──────────────────┬──────────────────┬─────────────────┐
│ 항목 │ React Native │ 순수 네이티브 │
├──────────────────┼──────────────────┼─────────────────┤
│ 언어 │ JavaScript │ Swift / Kotlin │
│ UI 렌더링 │ 네이티브 뷰 │ 네이티브 뷰 │
│ 성능 │ 근접하지만 오버헤드 존재 │ 최고 │
│ 코드 공유 │ iOS/Android 공유 │ 각각 작성 │
│ JS → Native 통신 │ JSI (C++ 브릿지) │ 직접 호출 │
│ 시작 시간 │ JS 엔진 초기화 │ 즉시 │
└──────────────────┴──────────────────┴─────────────────┘
Flutter와의 차이:
React Native: JS/TS → 네이티브 UI 컴포넌트 사용
Flutter: Dart → 자체 렌더러(Skia/Impeller)로 직접 그리기
핵심 요약
App.tsx (JSX/TSX)
↓ Metro (Babel 트랜스파일 + 번들링)
JS bundle
↓ Hermes bytecode(.hbc) 또는 다른 JS 엔진 로드
JS 런타임
↓ React Reconciler (Fiber diff)
Fabric Shadow Tree + Yoga
↓ JSI / TurboModules
네이티브 뷰 계층 (UIKit / Android View)
↓ Core Animation / RenderThread
GPU (Metal / Vulkan) → 프레임 버퍼
↓
모바일 디스플레이 픽셀 (60fps / 120fps)
↓
SoC 트랜지스터 (ON/OFF)
핵심: RN은 WebView가 아니다.
JS 런타임이 JSI/Fabric을 통해 실제 네이티브 UI 트리를 갱신한다.