React Native 공식 블로그에 New Architecture가 새로 소개되었을 때(https://reactnative.dev/blog/2024/04/22/release-0.74), 작업 중이던 프로젝트에서는 일부 이슈때문에 당장 업데이트가 불가한 상황이었다.
그렇게 잠시 잊고 살았는데 어느새 RN이 0.76버전까지 소개되었고, 이젠 New Architecture 위주의 업데이트가 이루어져서 더 늦기 전에 한번 정리해 둔 내용을 옮겨보려 한다.
우선, 왜 New Architecture가 나왔는지에 대한 정보가 필요하기 때문에 기존 구조에 대해 먼저 정리한다.
기존 RN의 구조는 다음과 같다.

- React: React는 애플리케이션의 UI를 선언적으로 정의하는 부분으로, React Native에서 UI 컴포넌트를 작성하고 상태 관리 및 이벤트 처리를 담당한다.
- Metro: Metro는 React Native의 번들러 역할을 수행한다. 작성된 JavaScript 코드를 JS Bundle로 묶어주는 역할을 하며, 앱이 실행될 때 이 번들을 로딩하게 된다.
- JS Bundle: Metro가 생성한 번들 파일로, 애플리케이션의 전체 JavaScript 코드가 포함되어 있다. JavaScript 코드는 JavaScriptCore(JSC) 엔진을 통해 JS Thread에서 실행된다.
- JS Thread: JavaScript 코드를 실행하는 스레드이다. 여기서 자바스크립트 로직과 애니메이션, 상태 관리 등을 처리된다. 직접 컨트롤이 불가한 네이티브 모듈과의 통신이 필요한 경우 항상 Bridge를 통해 Native 쪽과 소통해야 한다.
- Bridge: JS Thread와 Native 사이에서 데이터를 주고받는 통로 역할이다. 데이터를 JSON 형식으로 변환하여 JS에서 Native로, 또는 Native에서 JS로 전송한다.
- Shadow Thread: 메인 스레드와는 별개로 동작하는 백그라운드 스레드이다. UI 업데이트를 비동기적으로 처리하는 레이아웃 계산을 담당하는 스레드로, Yoga를 사용해 레이아웃을 계산하고 Shadow Tree 구조를 만드는데, 이 계산 결과는 Native UI로 전달된다. 이를 통해 메인 스레드의 부하를 줄이고 UI가 끊기지 않고 부드럽게 업데이트될 수 있도록 한다. 일반적으로 UI 요소들의 레이아웃 계산이나 스타일 변경 등과 같이 비교적 시간이 많이 소요되는 작업을 처리하는 데 사용된다.
- Yoga: Shadow Thread에서 작동하는 UI 요소들의 레이아웃을 계산하는 엔진이다. Flexbox 레이아웃 시스템을 기반으로 하여 UI 요소들의 배치와 크기를 계산하며 이 과정은 메인 스레드에서 수행된다. Yoga는 UI의 구조와 스타일을 바탕으로 UI 요소들을 올바르게 배치하고 크기를 조정하여 화면에 표시될 위치를 결정, 최종 레이아웃 결과를 Native 쪽에 전달한다.
- Native UI: JS에서 계산된 레이아웃 정보를 바탕으로 실제 UI가 렌더링 되는 네이티브 영역이다. 사용자에게 보이는 UI 요소들이 여기에서 만들어지고 업데이트된다.
- Native Modules: JS 코드가 네이티브 기능(예: 카메라, GPS 등)에 접근할 때 사용하는 네이티브 모듈이다. JS Thread에서 Bridge를 통해 호출된 네이티브 함수들이 여기서 처리된다.
요약하자면 JS Thread(RN)에서 네이티브 모듈 컨트롤을 직접 수행할 수 없어 Bridge를 거쳐 네이티브(iOS, Android) 단계에 접근하는 것이다.
이때, 네이티브 계층으로 전달해야 하는 모든 데이터를 직렬화하여 작동한다. JS Thread에서 Native Thread로의 data 통신 방법이 필요한데, JSON 형태로 직렬화하여 data를 전달하며 이 통로를 Bridge라고 부른다.
이 과정에서 Bridge 기반 통신이 event 생성 속도를 못따라감으로 인해 성능이슈가 발생하고 Bridge 과부하가 걸리게 된다.
신규 아키텍쳐는 이 Bridge가 본질적으로 가지고 있는 다음과 같은 제한적인 문제를 해결하기 위해 등장했다.
- 비동기: 비동기적이고 직렬화된 방식으로 데이터를 전달하기 때문에, 속도에 민감한 작업에는 제약이 발생한다. 애니메이션이나 제스처 처리와 같이 빠른 반응이 필요한 작업에서는 Bridge의 성능 한계로 인해 끊김 현상이 발생할 수 있다.
- single thread: javascript가 싱글 스레드에서 동작하기 때문에 bridge도 싱글 스레드로 동작한다.
- extra overheads (변환시 드는 과도한 비용): 각 메시지가 JSON으로 직렬화되어 보내지기 때문에 통신 과정에서 과도한 직렬화 및 역직렬화 비용이 크게 발생한다. 이는 복잡한 데이터나 빈번한 이벤트 통신에서 성능 저하를 유발할 수 있다.
종합적으로 Bridge에서의 성능 문제는 이벤트 생성 속도를 따라가지 못하기 때문인데, 특히 스크롤, 제스처와 같은 UI 상호작용에서 데이터 처리 속도가 느려지고, 프레임이 드롭되는 현상이 발생할 수 있다.
이를 해결하기 위해 RN 측에서는 0.74부터 도입된 New Architecture를 소개했는데, 이건 다음 포스팅에서 설명하도록 한다🥹
'개발 > React & React Native' 카테고리의 다른 글
[React] 리액트 원형 프로그래스 (Circle Progress Bar) 컴포넌트 만들기/예제 (1) | 2024.11.04 |
---|---|
[React Native] React Native의 New Architecture (JSI, JavaScript Interface) (5) | 2024.10.31 |
[React Native/iOS] 리액트 네이티브 환경에서 iOS Privacy Manifest 정책 대응하기 (0) | 2024.03.25 |
[React Native] patch-package를 사용해 라이브러리 커스텀하기 (0) | 2024.03.19 |
[React Native] Hermes engine이란? (0) | 2024.03.05 |