React Native의 새 아키텍처 개요, 도입 배경, 주요 기능(동기 레이아웃, 동시성 렌더러, JSI), 기대 효과와 사용 시점, Android와 iOS에서의 활성/비활성 방법을 설명합니다.
2018년부터 React Native 팀은 개발자가 더 높은 품질의 사용자 경험을 만들 수 있도록 React Native의 코어 내부 구조를 재설계해 왔습니다. 2024년을 기준으로, 이 버전의 React Native는 대규모 서비스에서 검증되었으며 Meta의 프로덕션 앱을 구동하고 있습니다.
새 아키텍처(New Architecture) 라는 용어는 새로운 프레임워크 아키텍처 자체와, 이를 오픈 소스로 가져오기 위한 작업 전체를 함께 가리킵니다.
새 아키텍처는 React Native 0.68부터 실험적인 옵트인 기능으로 제공되기 시작했으며, 이후 각 버전 릴리스마다 지속적으로 개선되고 있습니다. 현재 팀은 이 아키텍처를 React Native 오픈 소스 생태계에서 기본 경험(default)으로 만드는 작업을 진행 중입니다.
React Native로 수년간 개발을 진행해 오면서, 팀은 개발자가 고급스럽고 정교한 경험을 구현하는 것을 가로막는 여러 가지 한계를 발견했습니다. 이 한계들은 기존 프레임워크 설계에 근본적으로 내재된 것이었기에, 새 아키텍처는 React Native의 미래를 위한 투자로 시작되었습니다.
새 아키텍처는 기존 레거시 아키텍처에서는 불가능했던 기능과 개선 사항을 가능하게 합니다.
적응형 UI 경험을 구축하려면, 뷰의 크기와 위치를 측정하고 그에 따라 레이아웃을 조정해야 하는 경우가 자주 있습니다.
현재는 onLayout 이벤트를 사용해 뷰의 레이아웃 정보를 가져오고 필요한 조정을 합니다. 하지만 onLayout 콜백 내의 상태 업데이트는 이전 렌더가 그려진 뒤에 적용될 수 있습니다. 이 말은 곧, 사용자가 초기 레이아웃을 렌더링한 상태와 레이아웃 측정 결과에 대응해 업데이트한 상태 사이의 중간 단계나 화면이 "점프"하는 것처럼 보이는 현상을 볼 수 있다는 뜻입니다.
새 아키텍처에서는 레이아웃 정보에 동기적으로 접근하고, 중간 상태가 사용자에게 보이지 않도록 적절히 업데이트를 스케줄링함으로써 이러한 문제를 완전히 피할 수 있습니다.
예시: 툴팁 렌더링
새 아키텍처는 React 18 이상에서 제공되는 동시성 렌더링(concurrent rendering)과 관련 기능들을 지원합니다. 이제 데이터 페칭용 Suspense, Transitions, 기타 새로운 React API들을 React Native 코드에서도 사용할 수 있으며, 이를 통해 웹과 네이티브 React 개발 간의 코드베이스와 개념을 더욱 잘 맞출 수 있습니다.
동시성 렌더러는 또한 React에서 리렌더 횟수를 줄여주는 자동 배칭(automatic batching)과 같은 개선점을 기본으로 제공합니다.
예시: 자동 배칭(Automatic Batching)
Transitions 같은 새로운 동시성 기능은 UI 업데이트의 우선순위를 표현할 수 있는 능력을 제공합니다. 어떤 업데이트를 더 낮은 우선순위로 표시하면, React가 더 높은 우선순위의 업데이트를 처리하기 위해 해당 렌더링을 "중단(interrupt)"할 수 있습니다. 이렇게 하면 중요한 곳에서 사용자 경험이 더 반응성 있게 유지됩니다.
예시: startTransition 사용하기
새 아키텍처는 JavaScript와 네이티브 간의 비동기 브리지를 제거하고, 이를 JavaScript Interface(JSI)로 대체합니다. JSI는 JavaScript가 C++ 객체를, C++이 JavaScript 객체를 레퍼런스로 보유할 수 있게 해 주는 인터페이스입니다. 메모리 레퍼런스를 통해, 직렬화 비용 없이 메서드를 직접 호출할 수 있습니다.
JSI 덕분에 React Native에서 널리 사용되는 카메라 라이브러리인 VisionCamera는 프레임을 실시간으로 처리할 수 있습니다. 일반적인 프레임 버퍼는 약 30MB 정도이며, 프레임 레이트에 따라 초당 대략 2GB의 데이터에 해당합니다. 브리지의 직렬화 비용과 비교하면, JSI는 이 정도 규모의 인터페이싱 데이터를 무리 없이 처리할 수 있습니다. JSI는 데이터베이스, 이미지, 오디오 샘플 등 다른 복잡한 인스턴스 기반 타입도 노출할 수 있습니다.
새 아키텍처에서 JSI를 도입함으로써, 모든 네이티브–JavaScript 상호 운용 전반에서 이 종류의 직렬화 작업이 제거됩니다. 여기에는 View와 Text 같은 네이티브 코어 컴포넌트의 초기화 및 재렌더링도 포함됩니다. 새 아키텍처에서의 렌더링 성능 조사와 우리가 측정한 향상된 벤치마크에 대해 더 자세히 읽어 볼 수 있습니다.
새 아키텍처는 위에서 설명한 기능과 개선 사항들을 가능하게 하지만, 앱이나 라이브러리에서 새 아키텍처를 활성화한다고 해서 곧바로 성능이나 사용자 경험이 눈에 띄게 개선되는 것은 아닐 수 있습니다.
예를 들어, 동기 레이아웃 이펙트나 동시성 기능 같은 새로운 기능을 제대로 활용하려면 코드 리팩터링이 필요할 수 있습니다. JSI가 JavaScript와 네이티브 메모리 간의 오버헤드를 줄여 주기는 하지만, 애초에 데이터 직렬화가 앱 성능의 병목이 아니었을 수도 있습니다.
앱이나 라이브러리에서 새 아키텍처를 활성화하는 것은 React Native의 미래에 옵트인(opt-in)하는 것입니다.
팀은 새 아키텍처가 열어 주는 새로운 기능들을 적극적으로 연구하고 개발하고 있습니다. 예를 들어, Meta에서는 웹 정렬(web alignment)을 활발히 탐구하고 있으며, 이는 React Native 오픈 소스 생태계에도 제공될 예정입니다.
전용 discussions & proposals 저장소에서 논의 과정을 따라가거나 직접 기여할 수 있습니다.
0.76 버전부터, 새 아키텍처는 모든 React Native 프로젝트에서 기본으로 활성화되어 있습니다.
무언가 제대로 동작하지 않는 것을 발견하면, 이 템플릿을 사용해 이슈를 등록해 주세요.
어떤 이유에서든 새 아키텍처를 사용할 수 없다면, 여전히 옵트아웃(opt-out)할 수 있습니다.
android/gradle.properties 파일을 엽니다.newArchEnabled 플래그를 true에서 false로 변경합니다.gradle.properties
diff# Use this property to enable support to the new architecture. # This will allow you to use TurboModules and the Fabric render in # your application. You should enable this flag either if you want # to write custom TurboModules/Fabric components OR use libraries that # are providing them. -newArchEnabled=true +newArchEnabled=false
ios/Podfile 파일을 엽니다.ENV['RCT_NEW_ARCH_ENABLED'] = '0'를 추가합니다 (템플릿의 참고용 Podfile 참조).diff+ ENV['RCT_NEW_ARCH_ENABLED'] = '0' # Resolve react_native_pods.rb with node to allow for hoisting require Pod::Executable.execute_command('node', ['-p', 'require.resolve(`
shellbundle exec pod install