6.2 KiB
6.2 KiB
id, title, category, status, canonical_id, aliases, duplicate_of, source_trust_level, confidence_score, verification_status, tags, raw_sources, last_reinforced, github_commit, tech_stack
| id | title | category | status | canonical_id | aliases | duplicate_of | source_trust_level | confidence_score | verification_status | tags | raw_sources | last_reinforced | github_commit | tech_stack | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| wiki-2026-0508-jsi-javascript-interface | JSI (JavaScript Interface) | 10_Wiki/Topics | verified | self |
|
none | A | 0.9 | applied |
|
2026-05-10 | pending |
|
JSI (JavaScript Interface)
매 한 줄
"매 bridge 의 JSON serialization 의 제거 — 매 sync, direct C++ binding". React Native 의 New Architecture 의 foundation. 매 native function 을 C++ 객체로 expose, JS 가 매 sync 호출 + shared memory 접근. 매 old bridge 의 async-only / serialize-everything 의 근본 해결.
매 핵심
매 old bridge 문제
- 모든 JS↔Native 호출 의 JSON serialize → message queue → async dispatch.
- 매 frame 마다 hundreds of message — main thread blocking.
- Image, animation 의 latency 누적.
매 JSI 솔루션
- HostObject: C++ object 가 JS prototype 처럼 expose.
- Sync calls: 매 native function 의 즉시 invoke (no queue).
- Shared memory (ArrayBuffer): 매 zero-copy data exchange.
- TurboModules: JSI 기반 native module — lazy-loaded, typed.
- Fabric: JSI 기반 renderer — synchronous layout.
매 응용
- Reanimated 3+: UI thread 에서 매 worklet 의 sync 실행 (60→120Hz).
- MMKV: native key-value store 의 sync access (AsyncStorage 의 100x).
- VisionCamera: frame processor 의 native↔JS 의 zero-copy.
💻 패턴
TurboModule — JS 측 spec
// NativeCalculator.ts
import type { TurboModule } from 'react-native';
import { TurboModuleRegistry } from 'react-native';
export interface Spec extends TurboModule {
add(a: number, b: number): number; // 매 sync return
sha256(input: string): Promise<string>;
getConstants(): { version: string };
}
export default TurboModuleRegistry.getEnforcing<Spec>('Calculator');
TurboModule — iOS 구현
// Calculator.mm
#import "Calculator.h"
#import <RNCalculatorSpec/RNCalculatorSpec.h>
@implementation Calculator
RCT_EXPORT_MODULE()
- (NSNumber *)add:(double)a b:(double)b {
return @(a + b); // 매 sync, no bridge
}
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
(const facebook::react::ObjCTurboModule::InitParams &)params {
return std::make_shared<facebook::react::NativeCalculatorSpecJSI>(params);
}
@end
HostObject — direct C++ binding
// MyHostObject.cpp
#include <jsi/jsi.h>
using namespace facebook::jsi;
class MyHostObject : public HostObject {
public:
Value get(Runtime& rt, const PropNameID& name) override {
auto n = name.utf8(rt);
if (n == "fastFunction") {
return Function::createFromHostFunction(
rt, name, 1,
[](Runtime& rt, const Value&, const Value* args, size_t) -> Value {
double x = args[0].asNumber();
return Value(x * 2.0); // 매 sync, no JSON
});
}
return Value::undefined();
}
};
void install(Runtime& rt) {
auto obj = std::make_shared<MyHostObject>();
rt.global().setProperty(rt, "myNative", Object::createFromHostObject(rt, obj));
}
Reanimated worklet (JSI 활용)
import Animated, { useSharedValue, useAnimatedStyle, withSpring } from 'react-native-reanimated';
function Box() {
const x = useSharedValue(0); // 매 UI thread shared
const style = useAnimatedStyle(() => ({
transform: [{ translateX: x.value }],
})); // 매 worklet, UI thread 에서 sync 실행
return (
<Animated.View style={style} onTouchEnd={() => {
x.value = withSpring(100); // 매 JSI 의 sync update
}} />
);
}
MMKV (sync storage)
import { MMKV } from 'react-native-mmkv';
const storage = new MMKV();
storage.set('user.id', '123'); // 매 sync, no Promise
const id = storage.getString('user.id'); // 매 sync
// AsyncStorage: await storage.getItem(...) — 매 ms 단위 latency
VisionCamera frame processor
import { useFrameProcessor } from 'react-native-vision-camera';
import { detectFaces } from 'vision-camera-face-detector';
function Scanner() {
const frameProcessor = useFrameProcessor((frame) => {
'worklet';
const faces = detectFaces(frame); // 매 native, zero-copy
runOnJS(setFaces)(faces);
}, []);
return <Camera frameProcessor={frameProcessor} />;
}
Fabric component (synchronous layout)
// MyViewNativeComponent.ts
import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent';
import type { ViewProps } from 'react-native';
interface NativeProps extends ViewProps {
color?: string;
}
export default codegenNativeComponent<NativeProps>('MyView');
매 결정 기준
| 상황 | Approach |
|---|---|
| RN 0.68+ 새 project | New Architecture (Fabric+TurboModules) enable |
| Sync native 필요 | TurboModule + JSI |
| Animation 60+ FPS | Reanimated 3 worklet |
| Storage sync | MMKV (JSI) over AsyncStorage |
| Frame-by-frame ML | VisionCamera + JSI worklet |
기본값: New Architecture, TurboModules, Reanimated 3.
🔗 Graph
- 부모: React-Native · Hermes
- 변형: Old-Bridge · Fabric · TurboModules
- 응용: Reanimated · MMKV · VisionCamera
- Adjacent: Hermes-Bytecode · New-Architecture
🤖 LLM 활용
언제: RN 의 native module 작성, performance bottleneck 진단, sync API 필요. 언제 X: 매 plain JS-only feature, Expo Go 환경 (custom native 의 X).
❌ 안티패턴
- JSI sync function 에서 heavy work: JS thread block — 매 worklet / native thread 사용.
- HostObject 의 reference 누수: shared_ptr cycle — Runtime invalidate 시 crash.
- Old bridge + JSI 혼용: serialization overhead 잔존, 매 New Architecture full migration.
- Reanimated worklet 에서 closure capture 무분별: 매 'worklet' directive 누락 시 silent fall-back to JS thread.
🧪 검증 / 중복
- Verified (reactnative.dev/architecture, RN 0.76 New Architecture default 발표).
- 신뢰도 A.
🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — JSI + TurboModules 패턴 정리 |