React Native 0.76이 나오면서 New Architecture가 기본 활성화됐다. 기존에는 옵트인이었는데, 이제 새 프로젝트를 만들면 자동으로 켜진다.
이름은 거창한데 실제로 뭐가 바뀌는 건지 처음엔 잘 안 와닿았다. 기존 앱에 적용해보면서 느낀 것들을 정리해봤다.
핵심 변경: JSI와 Fabric
기존 아키텍처에서 JS 코드와 Native 코드는 비동기 브리지로 통신했다. 직렬화해서 주고받는 방식이라 속도가 느리고, 스레드를 넘어야 해서 레이턴시가 있었다.
New Architecture의 핵심은 두 가지다.
JSI (JavaScript Interface): JS에서 C++ 코드를 직접 호출할 수 있게 된다. 브리지를 거치지 않으니까 동기 호출이 가능하고, 복잡한 데이터도 직렬화 없이 참조로 넘길 수 있다.
Fabric: 새 렌더링 시스템이다. UI 업데이트가 메인 스레드에서 동기적으로 처리된다. 기존에는 JS → 브리지 → Native로 이동하면서 프레임 드랍이 생겼는데, Fabric에서는 이 레이턴시가 줄어든다.
체감 차이
스크롤이나 애니메이션에서 확실히 차이가 난다. Reanimated를 쓰는 화면에서 특히 부드러워졌다. 손가락을 따라가는 제스처 반응이 빠르다.
네이티브 모듈 호출도 빨라졌다. 카메라나 파일 시스템 접근처럼 빈번한 호출이 있는 기능에서 응답이 빠른 게 느껴진다.
마이그레이션 시 라이브러리 호환성 확인
기존 라이브러리 중 New Architecture를 지원 안 하는 게 있다. 라이브러리 README에 Fabric 또는 New Architecture 지원 여부를 확인해야 한다.
npx react-native-community/cli doctor
주요 라이브러리 대부분은 이미 지원하지만, 오래된 서드파티나 직접 만든 네이티브 모듈이 있다면 따로 확인이 필요하다.
커스텀 네이티브 모듈이 있다면
직접 만든 네이티브 모듈이 있다면 Turbo Modules로 마이그레이션해야 한다. 코드 구조가 꽤 바뀐다.
// Old Architecture (NativeModules 방식)
import { NativeModules } from 'react-native';
const { MyModule } = NativeModules;
MyModule.doSomething(); // 비동기 브리지
// New Architecture (Turbo Modules 방식)
import MyModule from './NativeMyModule';
MyModule.doSomething(); // JSI 직접 호출
타입 명세도 별도의 스펙 파일로 작성해야 하고, iOS와 Android 각각 수정이 필요하다. 네이티브 모듈 수가 많으면 시간이 걸린다.
당장 마이그레이션이 어렵다면
호환성 문제가 있어서 New Architecture를 당장 쓸 수 없다면 임시로 끌 수 있다.
iOS (ios/Podfile):
ENV['RCT_NEW_ARCH_ENABLED'] = '0'
Android (android/gradle.properties):
newArchEnabled=false
다만 이건 임시방편이다. 이후 메이저 버전에서 Old Architecture 지원이 없어질 수 있으니 마이그레이션 계획은 잡아두는 게 낫다.
Expo를 쓰고 있다면
Expo SDK 52부터 New Architecture가 기본이다. 별도 설정 없이 SDK를 업그레이드하면 자동으로 적용된다. 대신 Expo Go 앱이 New Architecture를 지원하지 않아서 개발 중에는 Expo Dev Client를 써야 한다.
새 프로젝트라면 그냥 기본 설정으로 쓰면 된다. 기존 프로젝트 마이그레이션은 라이브러리 호환성 체크가 시간을 제일 많이 잡는다. 서드파티 목록 먼저 훑어보고 시작하는 게 낫다.