| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | |||
| 5 | 6 | 7 | 8 | 9 | 10 | 11 |
| 12 | 13 | 14 | 15 | 16 | 17 | 18 |
| 19 | 20 | 21 | 22 | 23 | 24 | 25 |
| 26 | 27 | 28 | 29 | 30 | 31 |
- 삼성
- 정렬
- javascript
- 일본어공부
- 일본어학습지
- 백준
- 가벼운학습지후기
- 가벼운학습지
- 코딩테스트
- 코테준비
- 자바
- array
- SWEA
- 인프런
- mybatis
- 일본어독학
- 삼성소프트웨어아카데미
- 카카오
- js
- 코테
- 자료구조
- 프로그래머스
- 코딩
- 알고리즘
- 마이라이트
- stack
- 자바스크립트
- 스텍
- 성인학습지
- java
- Today
- Total
개발에 AtoZ까지
리액트 네이티브의 새로운 아키텍쳐는 뭘까? 본문
😀 개요
안녕하세요 😀
오늘은 리액트 네이티브의 새로운 아키텍처에 대해서 얘기해 보려고 합니다.
제 블로그를 자주 보시는 분이시라면 왜 뜬금없이 리액트 네이티브에 대해서 말할까라고 의문이 드실 수도 있어서 잠깐 부연 설명을 하려고 합니다 ㅎㅎ
현재 재직 중인 회사에서는 하이브리드앱의 대출 비교 서비스를 제공하고 있었습니다.
그런데 여러 가지 이유로 하이브리드가 아닌 순수 네이티브 앱으로 전환하는 선택을 하게 됐습니다. 이 경험은 다른 포스트로 찾아뵙겠습니다 ㅎㅎ
네이티브 앱을 전환할 때 기술 언어로는 크로스 플랫폼이 가능한 리액트 네이티브를 선택했고 그러다 보니 근래에는 리액트 네이티브에 대해서 많이 공부를 하고 있어서 그와 관련된 내용을 공유하고 싶었습니다.
🔍 0.68 미만 버전에서의 리액트 네이티브는 어땠을까?
몇년전부터 크로스 플랫폼에 대한 키워드가 핫했습니다. 최근에는 토스로인해 국내에서는 더 핫해졌다고 생각합니다.
그 이유는 아무래도 서로 다른 IOS/AOS 두가지 OS를 하나의 코드로 개발할 수 있다는 점때문이라고 생각합니다.
이렇게 됐을때는 각각의 OS 개발자가 개발하는것보다 개발생산성과 개발의 통일성을 가질 수 있기 때문에 장점이 독보적입니다.
그러면 리액트 네이티브는 어떻게 하나의 코드로 IOS/AOS 에서 실행이 되는걸까? 의문이 생기실겁니다.
리액트 네이티브의 핵심 메커니즘은 Bridge(연결다리)라는 개념입니다.
Bridge는 JS와 네이티브 분리된 두 영역을 message-queue 방식으로 서로 소통할 수 있게 해주는 메커니즘입니다.
이 메커니즘을 활용해 JSON 으로 서로 소통합니다.
아무래도 JS, 네이티브의 생태계가 다르니 두 생태계를 아우를 수 있는 소통방식이 필요했습니다. 그게 JSON 입니다.
단계별로 살펴보겠습니다.
- JSX 코드 작성

- 해당 코드를 JSON으로 변형(직렬화)
- JSON 직렬화된 데이터를 Bridge를 통해서 네이티브 영역으로 전달
- 네이티브영역에서는 수신받은 JSON을 역직렬화해서 UI 렌더링
크게는 위와 같은 단계로 UI가 렌더링 됩니다.
그런데 여기서 또 의문이 생길 수 있는것이 JSON 직렬화가 특별한건가?? 실제 JSX로 표현되는 컴포넌트들이 모두 네이티브가 이해하는 컴포넌트들인가? 라는 의문이 생길겁니다.
맞습니다. JSX의 컴포넌트들이 모두 네이티브에서 인식되는 것은 아닙니다. 특히 FlexBox는 네이티브에서 없는 개념입니다.
이런 FlexBox 매커니즘을 네이티브가 이해할 수 있게 도와주는 시스템이 Yoga입니다.
Yoga 시스템은 실질적으로 네이티브 View를 렌더링 하지는 않습니다. 리액트 메커니즘을 통해 생성된 ReactElementTree를 이해하고 그것을 네이티브에 맞게 box(=div)의 크기와 위치를 결정하는것까지만 Yoga의 역할 입니다.
이렇게 UI를 그리는 명령과 상호 간의 소통을 Queue 방식의 JSON으로 진행하다 보니 여러 가지 문제가 있습니다.
비동기 방식으로 동작하기 때문에 이미 요청해버린 렌더링이나 작업들에 대해서는 중간에 취소할 수 없고 또 이 과정 속에서 매 순간 발생하는 JSON의 직렬화/역직렬화로 인한 불필요한 오버헤드가 발생하다 보니 성능상의 이슈가 있습니다.

조금 더 자세한 예시를 들어보겠습니다.
아주 많은 양의 컨텐츠를 리스트로 그리는 스크린이 있다고 가정해 보겠습니다. 이런 상황에서 사용자가 엄청 빠르게 리스트를 스크롤 하게 되면 화면은 어떻게 될까요??
아마 스크롤 도중에 빈 리스트 화면이 중간중간 보이게 될 것입니다. 왜냐하면 네이티브가 스크롤 감지해서 메시지를 직렬화하여 JS 영역으로 전달하고 JS 영역에서는 다시 역직렬화해서 거기에 맏는 콜백함수를 찾고 그 찾은 내용을 다시 네이티브 영역으로 직렬화 하는등 무거운 작업들로 인해 화면 렌더링이 스크롤 속도를 따라가지 못하게 되는 것입니다.
📌 그러면 새로운 아키텍처는 어떻게 개선시켰을까?
이전 아키텍처의 가장 큰 문제점은 렌더링 및 동작 실행 시 필요한 JSON의 직렬화/역직렬화 입니다. 그래서 새로운 아키텍처에서는 이 부분을 개선했습니다.

이전 아키텍처와 새로운 아키텍처를 비교해 보면 중간에 Bridge를 JSI로 대체된 것을 볼 수 있습니다.
JSI는 Javascript Interface라고 해서 자바스크립트 엔진이 리액트 네이티브와 직접적으로 통신 할 수있게 해주는 인터페이스입니다. 기존에는 JSON으로 통신하기 위해 양측간 직렬화/역직렬화를 했다면 새로운 아키텍처에서는 직렬화/역직렬화 필요없이 JSI가 직접 네이티브의 함수를 호출합니다.
JSI이 생소할 수 있으니 간단한 예제 코드를 보겠습니다.
package com.yourapp;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.module.annotations.ReactModule;
@ReactModule(name = DeviceNameModule.NAME)
public class DeviceNameModule extends ReactContextBaseJavaModule {
public static final String NAME = "DeviceNameModule";
public DeviceNameModule(ReactApplicationContext reactContext) {
super(reactContext);
}
@Override
public String getName() {
return NAME;
}
public String getDeviceName() {
return android.os.Build.MODEL;
}
}
import { useEffect } from 'react';
const useDeviceName = () => {
useEffect(() => {
const deviceName = global.getDeviceName();
console.log('Device Name:', deviceName);
}, []);
return deviceName;
};
export default useDeviceName;
위의 예제는 기기명을 가져오는 인터페이스를 작성한 것입니다.
네이티브 영역에 module을 만들어주고 해당 모듈을 JS 영역에서 사용할 수 있도록 인터페이스를 만들어줬습니다. 이렇게 네이티브와 JS가 동일한 인터페이스를 사용하여 상호작용하게끔 하는것이 JSI입니다.
그래서 JSI를 사용하면 정확히 어떤 부분이 장점인가요?
JSI를 통해서 성능이 향상됐습니다. 어떤 부분에서 성능이 향상됐을까요??
첫 번쨰는 JS가 직접 동기식으로 함수를 호출 하다보니 기존에 비동기적으로 소통했던 JSON 방식보다 성능이 크게 향상됐습니다.
두 번째는 JS와 네이티브 코드가 동일한 메모리 공간을 공유할 수 있기 때문에 불필요한 자원을 따로 만들지 않기 때문에 크게 성능이 향상됐습니다.
이외에도 여러 가지 측면에서 성능이 향상됐습니다.
🫡 마무리
이번 포스팅을 작성하면서 많은것을 느낄 수 있었다.
기술은 지속적으로 발전한다. 발전에 맞춰서 사용법만을 익히기 보다는 어떤 문제점이 있었고, 어떻게 해결하며 발전했는지 그 이유를 아는것이 제대로 기술을 사용하는 방법이라고 생각하는 시간이 됐다.
'프론트엔드' 카테고리의 다른 글
| [Error 노트] vite에서 env 설정하는 방법 (0) | 2026.07.05 |
|---|---|
| Module not found: Error: Can't resolve 'next-swc-loader' in ~ (0) | 2023.02.03 |
