[G1-Sync] Manual knowledge update
This commit is contained in:
@@ -0,0 +1,103 @@
|
||||
---
|
||||
id: react-native-bridge-performance
|
||||
title: React Native — Bridge / JSI 성능
|
||||
category: Coding
|
||||
status: draft
|
||||
source_trust_level: B
|
||||
verification_status: conceptual
|
||||
created_at: 2026-05-09
|
||||
updated_at: 2026-05-09
|
||||
tags: [react-native, performance, bridge, jsi, vibe-coding]
|
||||
tech_stack: { language: "TS / Swift / Kotlin", applicable_to: ["React Native 0.74+"] }
|
||||
applied_in: []
|
||||
aliases: [Fabric, TurboModules, Hermes, new architecture]
|
||||
---
|
||||
|
||||
# React Native — Bridge / JSI 성능
|
||||
|
||||
> Old architecture: JS ↔ Native 가 async JSON bridge. 큰 데이터 / 자주 호출 = 병목. **New Architecture (JSI / TurboModules / Fabric)** 는 동기 ref 호출 — 속도 차이 큼. 0.74+ 부터 default 권장.
|
||||
|
||||
## 📖 핵심 개념
|
||||
- **JSI (JavaScript Interface)**: JS 가 native 메서드를 직접 invoke. 동기 가능.
|
||||
- **TurboModules**: 지연 로딩 + 타입 정의 (codegen) + JSI 기반 호출.
|
||||
- **Fabric**: 새 renderer. UI 트리를 host platform 직접.
|
||||
- **Hermes**: RN 의 JS engine. JSC 보다 startup / 메모리 우수.
|
||||
|
||||
## 💻 코드 패턴
|
||||
|
||||
### 큰 list — FlatList → FlashList
|
||||
```tsx
|
||||
import { FlashList } from '@shopify/flash-list';
|
||||
|
||||
<FlashList
|
||||
data={items}
|
||||
estimatedItemSize={80}
|
||||
renderItem={({ item }) => <Row item={item} />}
|
||||
keyExtractor={item => item.id}
|
||||
/>
|
||||
// FlatList 보다 메모리 / 스크롤 부드러움
|
||||
```
|
||||
|
||||
### 무거운 작업 — 별도 thread
|
||||
```tsx
|
||||
import { runOnJS, runOnUI } from 'react-native-reanimated';
|
||||
|
||||
// Reanimated worklet — UI thread 에서 실행
|
||||
const tap = Gesture.Tap().onEnd(() => {
|
||||
runOnJS(setActive)(true);
|
||||
});
|
||||
```
|
||||
|
||||
### Native 모듈 호출 batching
|
||||
```tsx
|
||||
// ❌ 1000번 개별 호출
|
||||
for (let i = 0; i < 1000; i++) NativeMod.compute(i);
|
||||
|
||||
// ✅ 한 번에
|
||||
NativeMod.computeBatch(Array.from({ length: 1000 }, (_, i) => i));
|
||||
```
|
||||
|
||||
### 이미지 — 캐싱 + 리사이즈
|
||||
```tsx
|
||||
import FastImage from 'react-native-fast-image';
|
||||
|
||||
<FastImage
|
||||
source={{ uri, priority: FastImage.priority.normal, cache: FastImage.cacheControl.immutable }}
|
||||
resizeMode={FastImage.resizeMode.cover}
|
||||
/>
|
||||
```
|
||||
|
||||
### Hermes 활성화 (0.70+ 기본)
|
||||
```js
|
||||
// android/app/build.gradle
|
||||
project.ext.react = [ enableHermes: true ]
|
||||
// iOS Podfile use_react_native!(:hermes_enabled => true)
|
||||
```
|
||||
|
||||
## 🤔 의사결정 기준
|
||||
| 영역 | 권장 |
|
||||
|---|---|
|
||||
| Long list | FlashList > FlatList > ScrollView |
|
||||
| Animation | Reanimated 3 (UI thread) |
|
||||
| Gesture | react-native-gesture-handler |
|
||||
| Image | FastImage 또는 Expo Image |
|
||||
| Maps | react-native-maps + nativeRef API |
|
||||
| Network | fetch + 캐시 (RNTQ / SWR / RTK Query) |
|
||||
| 백그라운드 | RN 자체 약함 — 네이티브 코드 또는 Expo TaskManager |
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **map / setState 매 FPS 호출**: bridge spam → 60fps 깨짐.
|
||||
- **큰 base64 image 를 props 로**: bridge 폭주. URI / 캐시 사용.
|
||||
- **synchronous 가정 (old arch)**: bridge 는 async. 응답 기다리지 마라.
|
||||
- **InteractionManager 무시 — animation 도중 setState**: 끊김. afterInteractions 안에서.
|
||||
- **production 에서 console.log 남김**: bridge 호출 빈도 ↑. dev only.
|
||||
- **Reanimated worklet 안에서 일반 JS 변수 mutation**: shared value 사용.
|
||||
- **모든 모듈을 default index.js 에서 import**: startup 느려짐. lazy import.
|
||||
|
||||
## 🤖 LLM 활용 힌트
|
||||
- "New Architecture (Fabric + TurboModules + Hermes) 가정. List = FlashList, animation = Reanimated 3" 명시.
|
||||
- bridge spam 패턴 (per-frame setState) 작성하면 막기.
|
||||
|
||||
## 🔗 관련 문서
|
||||
- [[React_Rendering_Optimization]]
|
||||
- [[Backpressure_Patterns]]
|
||||
Reference in New Issue
Block a user