[React Native] New Architecture 이해하기 - 2. JSI

jiveloper·2025년 5월 4일

React Native

목록 보기
17/18
post-thumbnail

안녕하세요~~~ ☺️👋 벌써 React Native New Architecture 3번째 시간입니다.
오늘은 새로운 아키텍처의 핵심 구성 요소라고 할 수 있는 JSI에 대해 포스팅해보려 합니다!
(Codegen이전 포스팅을 참고해주세요.)

새로운 아키텍처를 이해할 때 가장 중요한 포인트는 JavaScript와 네이티브가 어떻게 연결되는가? 입니다.

JSI는 JavaScript와 네이티브를 연결해주는 인터페이스로, 구 아키텍처의 브릿지 역할을 대체하기 위해 ☄️혜성같이☄️ 등장했습니다. JSI가 무엇이고, 어떻게 기존 브릿지의 역할을 대체하는지 자세히 알아봅시다! 👀



JSI가 뭔데?

1. JSI 정의

JSI(JavaScript Interface)는 기존 아키텍처의 브릿지를 대체하여 JavaScript와 네이티브를 직접 연결할 수 있도록 해주는 C++ 기반 인터페이스입니다. JSI는 C++ 힙 메모리에 직접 생성되며, JavaScript 엔진은 이 객체에 대한 포인터를 가지게 됩니다. 이로 인해 JavaScript와 네이티브 코드가 서로의 메모리 공간을 공유하게 되어 자바스크립트와 네이티브 간의 경계가 없어질 수 있게 됩니다.

2. JSI를 기반으로 동작하는 핵심 구성 요소들

JSI를 통해 아래의 구성 요소들이 JavaScript와 직접 연결됩니다.

1. Hermes 엔진
Hermes는 기기에서 JavaScript 코드를 실행하는 JavaScript 엔진이며, JSI를 통해 네이티브 코드와 직접 연결됩니다. JSI는 런타임에 접근할 수 있는 인터페이스를 제공하여, JavaScript에서 네이티브 함수나 객체를 직접 호출할 수 있게 합니다.

2. Turbo Module
TurboModuleJSI를 통해 JavaScript에서 브릿지 없이 네이티브 메서드를 호출할 수 있도록 구현되어 있습니다.

3. Fabric
FabricJSI를 기반으로 JavaScript와 네이티브 UI 렌더러를 연결하는 새로운 렌더링 엔진입니다.

(위 구성 요소들에 대해서는 다음 포스팅에서 자세히 살펴볼 예정 입니다! 🤩)



JSI는 네이티브 메서드를 어떻게 호출할까?

1. HostObject를 통한 네이티브 메서드 접근

JSI를 통해 네이티브 메서드는 C++ 객체 형태로 JavaScript에 노출되며, JavaScript 코드에서 이를 참조하고 직접 호출할 수 있습니다. 이때 노출된 C++ 객체를 HostObject 라고 부릅니다. HostObjectJSI에서 매우 중요한 개념으로, 런타임에 등록된 구현체가 JavaScript 코드 내에서 직접 참조될 수 있고, JavaScript 코드는 네이티브 메서드를 마치 자체 메서드처럼 호출할 수 있습니다.
(이는 마치 웹에서 JavaScript가 모든 DOM 요소를 참조하고, 해당 메서드를 호출하는 방식과 유사합니다. 🙂)


2. JavaScript에서 네이티브 모듈을 호출하기까지

1. 앱 시작 시, Codegen은 모듈의 인터페이스를 정의
이전 포스팅 내용을 잠깐 복습하자면, Codegen은 빌드 과정에서 모듈의 C++ 기반 인터페이스를 생성합니다. JSI는 이 인터페이스를 기준으로 어떤 모듈을 찾아야 하는지, 어떤 메서드를 호출해야하는지 알 수 있습니다. 이 인터페이스 정의가 없다면, JSI는 필요한 모듈을 알 수 없습니다. 😭😭

2. JavaScript에서 모듈 호출
새로운 아키텍처에서는 Turbo Module을 사용하여 네이티브 모듈을 구현합니다. JavaScript에서 이 모듈을 호출할 때, JSI는 가장 먼저 Codegen이 정의한 인터페이스를 참조합니다. 최초 호출인 경우 해당 모듈이 로드되어 있지 않으므로, JSI는 모듈을 동적으로 로드하고 초기화한 뒤 호출합니다. 이미 로드된 경우는 모듈을 바로 호출합니다.



JSI의 특징

JSI에는 다음과 같은 특징이 있어, 여러가지 이점을 가져다줍니다. 대표적으로 세가지 특징을 설명드리겠습니다!🥹

  • 동시성 : JavaScript는 UI 스레드에서 실행되는 함수를 직접 호출할 수 있습니다.

  • 오버헤드 감소 : 새로운 아키텍처는 더 이상 데이터를 직렬화하거나 역직렬화할 필요가 없으므로 직렬화로 인한 추가 비용이 발생하지 않습니다.

  • 동기 방식 : JSI는 비동기/동기 방식을 모두 지원하지만, 비동기적으로 실행 되어서는 안 되는 함수들은 동기적으로 실행할 수 있습니다.

제가 그중에서도 가장 강조하고 싶은 특징이 세번째 특징인 동기 방식 부분인데요, JSI의 동기 방식이 어떤 이점을 가져왔는지 자세히 알아봅시다!! 😎

JSI는 동기적으로도 실행될 거라구우!

비동기 호출은 UI 스레드나 JavaScript 스레드를 차단하지 않기 때문에 대부분의 경우 여전히 선호됩니다. 하지만 다음과 같은 상황에서는 동기 호출이 유익할 수 있습니다.

  • 네이티브 모듈 초기화
    일부 네이티브 모듈은 사용하기 전에 초기화해야 하는데, 비동기적으로 초기화할 경우 지연이나 충돌이 발생할 수 있습니다. JSI를 사용하면 네이티브 모듈을 동기적으로 초기화하여 이러한 문제를 방지할 수 있습니다.

  • 상수 접근
    일부 네이티브 모듈은 장치 정보나 플랫폼별 값과 같이 JavaScript 코드에서 사용되는 상수를 노출합니다. (ex. OS, 장치 이름, 앱 버전 등등..) JSI를 사용하면 이러한 상수에 브릿지 메시지를 기다릴 필요 없이 JavaScript에서 동기적으로 접근할 수 있습니다.

  • 동기식 네이티브 메서드 호출
    일부 네이티브 메서드는 클립보드 접근이나 현재 위치 가져오기처럼 JavaScript 코드에 값을 즉시 반환해야 합니다. JSI를 사용하면 콜백이나 프로미스를 사용하지 않고도 이러한 메서드를 JavaScript에서 동기적으로 호출할 수 있습니다.



마무리

Bridge의 비효율적인 통신 한계를 해결하기 위해 ☄️혜성같이☄️ 등장한 우리 JSI...!
BridgeJSI를 한 눈에 비교해보며... Bridge를 이제 그만 보내주도록 하겠습니다...🥹🥹


구분BridgeJSI
모듈 등록 시점앱 구동 시, ReactPackage 목록을 통해 Java/ObjC 모듈을 한 번에 등록앱 실행 시, C++ 객체를 JS 런타임(globalThis)에 직접 주입
데이터 전달 방식JS ↔ Bridge 간 JSON 직렬화/역직렬화JS ↔ C++ 간 메모리 직접 접근 (함수 포인터 호출)
호출 타이밍비동기 (Bridge 메시지 큐 통해 전달)동기/비동기 모두 가능 (C++ 런타임에서 직접 실행)
핵심 특징모듈을 미리 다 등록해두고 이름으로 호출런타임에 직접 바인딩하고 바로 실행

Bridge 방식은 이제 안녕 👋
JSI는 브릿지를 대체하기에 매우 적절!! +_+

다음 포스팅에서는 새로운 아키텍처의 다른 구성 요소인 Hermes 엔진에 대해 알아보겠습니다!

그럼 다음 포스팅에서 만나요~~ 🥹👋



참고

https://github.com/anisurrahman072/React-Native-Advanced-Guide/blob/master/New-Architecture/New-Architecture-in-depth.md#jsi-javascript-interface

https://medium.com/mj-studio/react-native-new-architecture-guide-9fd045438530

profile
👩🏻‍💻 글을 쉽고 재미있게 전달하고 싶은 모바일 앱 개발자입니다.

0개의 댓글