React Native Deep dive

Seoyong Lee·2023년 7월 9일
13

개발 공부

목록 보기
2/21
post-thumbnail

현재 앱 개발을 위해 사용하고 있는 리액트 네이티브의 개념과 원리에 대해서 찐하게 알아보았습니다.

Learn once, write anywhere.한 번 배우고, 어디서나 작성하세요.

React Native 공식문서 - React Native - Learn once, write anywhere

리액트 네이티브란?

리액트 네이티브는 iOS와 안드로이드에서 동작하는 네이티브 모바일 앱을 만들기 위한 자바스크립트 프레임워크입니다. 실제로 페이스북, 에어비앤비, 토스 등은 이미 리액트 네이티브로 만든 앱을 사용자에게 제공하고 있습니다.

리액트 네이티브가 코르도바(Cordova)나 아이오닉(Ionic)과 같은 기존 크로스 플랫폼 앱 개발 방법과 다른 점은 바로 대상 플랫폼의 표준 렌더링 API를 사용한다는 점입니다. JS, HTML, CSS를 사용하여 모바일 앱을 만드는 기존 방법은 웹뷰(webview)를 이용하여 렌더링하여 성능이 떨어지고 네이티브 UI 요소를 어색하게 흉내내는 것에 만족해야 했습니다. 리액트 네이티브는 여러분이 작성한 마크업을 플랫폼에 상응하는 진짜 네이티브 엘리먼트로 전환합니다. 또한 메인 UI 스레드와 분리되어 실행되기에 앱의 역량을 줄이지 않고도 빠른 성능을 유지할 수 있습니다.

리액트 네이티브의 장점을 요약하면 다음과 같습니다.

  • 쉬운 개발 경험
  • 플랫폼별 코드 재사용
  • 지식과 리소스의 공유

그러나 리액트 네이티브는 다음의 단점도 가지고 있습니다.

  • 추가 레이어로 인한 디버깅의 어려움
  • 대상 플랫폼의 API 버전 업데이트에 대응하는 기간 필요

결론적으로 리액트 네이티브는 기존 자바스크립트의 코드나 지식을 공유하여 빠르게 모바일 앱을 만들고 싶은 경우 유용합니다.

리액트 네이티브의 작동 원리

리액트 네이티브의 동작 원리는 리액트의 가상(virtual) DOM과 관련되어 있습니다. DOM 수정은 매우 값비싼 동작이기 때문에 리액트는 페이지의 변화를 바로 렌더링 하는 대신 메모리의 가상 DOM을 이용해 변화가 필요한 곳을 계산하고 최소한의 변경사항만 렌더링합니다. 리액트 네이티브는 같은 원리를 이용해 브라우저의 DOM이 아닌 오브젝티브-C API를 호출하여 iOS 컴포넌트를 렌더링하고, 자바 API를 호출하여 안드로이드 컴포넌트를 렌더링합니다. 이는 브릿지가 대상 플랫폼의 네이티브 UI 요소에 접근하는 인터페이스를 제공하기 때문에 가능합니다.

neoito.com - What is React Native?

RN 플랫폼 파트

그렇다면 실제로 리액트 네이티브는 어떤 파트로 구성되어 있는지 살펴보겠습니다.

1. 네이티브 코드 / 모듈

  • 네이티브 코드는 보통 iOS의 경우 C 나 Swift, Android의 경우 자바나 코틀린으로 작성되어 있습니다. 그러나 리액트 네이티브(이하 RN)에서 이런 네이티브 코드를 직접 작성할 일은 거의 없습니다.

2. JavaScipt VM

  • 모든 자바스크립트 코드는 JS 버츄얼 머신(VM)을 통해 작동되며, iOS/Android simulator와 기기는 JavaScriptCore 엔진을 사용합니다. JavaScriptCore는 WebKit을 위해 제작된 오픈소스로 사용하는 대표적인 브라우저는 Safari 입니다.
  • iOS의 경우 iOS platform에서 제공하는 JavaScriptCore를 사용합니다. 이는 iOS 7 (OS X Mavericks) 에서 처음 소개되었습니다.

3. React Native Bridge (New Architecture 이전)

  • RN bridge는 C++/Java 로 제작되어 네이티브와 자바스크립트 스레드 사이의 통신을 가능하게 해줍니다.
  • 메시지 전달을 위한 커스텀 프로토콜이 사용됩니다.

어플리케이션 동작 순서

어플리케이션은 다음 순서로 동작합니다.

  1. 터미널에서 react-native run-ios 혹은 react-native run-android 를 실행
  2. RN CLI는 웹팩과 유사하게 JS 코드를 하나의 main.bundle.js 파일로 번들링 해주는 node packager/bundler를 실행
  3. 네이티브 스레드는 번들링된 JS 코드를 실행시키는 JS VM 스레드를 생성
  4. 네이티브 스레드는 RN 브릿지 JS 앱을 실행시키도록 메시지 전달
  5. 생성된 JS 스레드는 RN 브릿지를 이용해 네이티브 쓰레드에 지시 사항 전달
    ex) [ [2,3,[2,'Text',{...}]] [2,3,[3,'View',{...}]] ]
  6. 네이티브 스레드는 지시 사항을 수행하고 결과물을 JS에 전달하여 수행 결과를 알림
  • RN 브릿지 메시지를 콘솔에서 확인해 보려면 …
import MessageQueue from 'react-native/Libraries/BatchedBridge/MessageQueue';
MessageQueue.spy(true);

스레딩 모델

리액트 네이티브는 다음의 다중 스레드 모델로 구성되어 있습니다.

메인 스레드 (Native Queue)

  • 프로그램이 시작되자마자 생성되는 기본 스레드입니다
  • 앱을 로드하며 Javascript 코드 실행을 위한 JS 스레드를 실행시킵니다
  • '누름', '터치' 등과 같은 UI 이벤트를 수신하여 RN 브리지를 통해 JS 스레드로 전달합니다
  • Javascript가 로드되면 JS 스레드는 화면에 렌더링해야 하는 항목에 대한 정보를 보냅니다. 이 정보는 섀도우 스레드에서 레이아웃 계산에 사용됩니다
  • 마지막으로 이러한 지시사항은 뷰 렌더링을 위해 다시 기본 스레드로 전달됩니다

JS 스레드 (JS Queue)

  • JS 큐는 JS 스레드가 실행되는 스레드 큐 입니다. JS 스레드는 모든 비즈니스 로직, 즉 RN으로 작성된 코드를 실행합니다.

섀도우 스레드

  • 섀도우 스레드는 기본적으로 뷰 위치를 계산하는 방법을 결정하는 수학적 엔진과 같습니다.
  • 섀도우 스레드는 레이아웃을 계산하는 데 필요한 정보만 있는 기본 객체인 섀도우 노드로 이루어져 있습니다.

네이티브 모듈

  • RN에 의해 생성된 스레드 외에도 애플리케이션의 성능을 높이기 위해 커스텀 네이티브 모듈에 스레드를 생성할 수도 있습니다. 예를 들어 애니메이션은 JS 스레드에서 작업 부하를 줄이기 위해 별도의 네이티브 스레드에 의해서 처리됩니다.

New Architecture의 등장(2022)

지금까지 리액트 네이티브의 작동 원리에 대해서 알아보았습니다. 사실 위 내용은 2022년 New Architecture의 등장으로 조금 변화하게 됩니다. New Architecture의 가장 큰 차이점은 바로 브릿지 모듈을 없애고 JSI(JavaScript Interface)를 도입했다는 점입니다. 그렇다면 기존 방식이 어떤 문제를 가지고 있었기에 새로운 방식이 도입된 것일까요?

New Architecture가 해결하려는 문제

The New Architecture is Here... What Now? - Lorenzo Sciandra

일단 기존 방식에서 가장 큰 문제는 JSON을 통해 네이티브와 통신하는 브릿지 모듈입니다. 하나의 브릿지를 통해 통신했기 때문에 쉽게 병목현상이 발생하였고 JS 스레드와 네이티브 스레드가 서로의 존재를 모르는 상태로 JSON 데이터를 보내왔기 때문에 여러 문제가 발생하였습니다. 어떤 네이티브 모듈이 사용될지 몰라 처음에 모든 네이티브 모듈을 로드해야 하는 부분도 문제였습니다.

이러한 문제를 해결하기 위해 New Architecture에선 JSI(JavaScript Interface)를 도입하게 됩니다. JSI는 C++로 작성되어 JSON 없이 바로 네이티브 단계의 메소드를 invoke/call 할 수 있는 모듈입니다. JSI는 기존 브릿지 모듈에 비해 다음 장점을 가집니다.

  • lightweight

    • JS 코드로 직접 네이티브 언어와 통신이 가능하게 되면서 브릿지가 유발하던 병목현상을 해결하였습니다
    • 실제 사용되는 시점에 필요한 네이티브 모듈(ex 블루투스 등)을 불러오기 때문에 가볍습니다(이를 해결하기 위해 Turbo Modules가 추가되었습니다)
  • general-purpose

    • 기존 JS Core Engine에만 특화되어 있던 브릿지와 달리 JSI는 엔진에서의 종속을 벗어나 v8, Chakra 등 다른 JS엔진을 자유롭게 선택할 수 있습니다.
  • written in C++

    • 네이티브 모듈에 대한 reference를 JS 코드로 들고 있도록 하여 JSON 변환 과정을 없앴습니다.
    • 이 방식은 웹에서 JS코드가 DOM element에 대한 reference를 들고 있는 것과 비슷합니다.
    • 네이티브 모듈과 직접 통신하게 되면서 브릿지가 유발하던 비동기 관련 이슈도 자연스럽게 해결되었습니다
    • C++ 은 Statically Typed Language 입니다. 따라서 static type check를 위해 CodeGen이 추가되었습니다

제한 사항들

위와 같이 New Architecture의 도입으로 리액트 네이티브가 가지고 있던 여러 문제가 개선된 것 같지만 RN 코어 메인테이너인 Lorenzo Sciandra에 따르면 아직 다음의 문제점이 존재합니다.

1. Typing

  • 브릿지 모듈이 C++을 사용하는 JSI로 바뀌면서 정적타입 언어 사용이 이전에 비해 조금 더 강제됩니다
  • 기존에 TypeScript를 사용하고 있었다면 큰 문제는 없겠지만 그렇지 않다면 부담이 될 수 있습니다
  • 아직 모든 타입을 완벽하게 지원하지는 않습니다 (Custom Type 등)

2. New arch configuration

3. Third party libraries

  • 아직 많은 라이브러리가 New Architecture를 완벽하게 지원하지 않을 수 있습니다
  • React 18에서 새로 추가된 automatic batching은 상태관리와 관련해서 문제가 될 수 있으므로 사용 중인 상태관리 라이브러리가 React18을 지원하는지 확인하는 것을 권장합니다

결론적으로 New Architecture는 기존 문제점들을 많이 해결하였지만, 아직 RN을 사용하는 써드파티 라이브러리들이 완벽하게 이를 지원하지 않기 때문에 당분간은 문제가 생길 수 있다는 점을 인지하면서 사용하면 좋을 것 같습니다.

지금까지 새로 추가된 New Architecture의 개념과 장단점에 대해서 알아보았습니다. 앞으로 시간이 더 지나면 기존 방식은 자연스럽게 모두 새로운 방식으로 대체될 것으로 예상됩니다. 하나의 언어로 여러 OS에서 작동하는 서비스를 만든다는 것은 충분히 매력적인 기술입니다. 언젠가는 리액트 네이티브를 대체할 새로운 대안이 등장할 수도 있지만 현재 개발자들이 고민하고 해결했던 방식에 대해 알아두는 것은 미래에도 분명히 도움이 될 것입니다.

참고:
https://www.reactnative.guide/3-react-native-internals/3.1-react-native-internals.html
https://www.youtube.com/watch?v=0MlT74erp60
https://www.aladin.co.kr/shop/wproduct.aspx?ItemId=158501368
https://medium.com/coox-tech/deep-dive-into-react-natives-new-architecture-fb67ae615ccd

5개의 댓글

comment-user-thumbnail
2023년 7월 10일

진짜 좋은 글이네요 감사함니다

1개의 답글
comment-user-thumbnail
2023년 7월 16일

최근 메인 서비스 앱을 React Native 로 재작성하여 오픈했는데, 부랴부랴 기능만 만드느라 놓쳤던 부분들도 알게됐네요!
좋은 글 감사합니다 :)

답글 달기
comment-user-thumbnail
2023년 7월 20일

좋은 글 감사합니다

답글 달기
comment-user-thumbnail
2024년 8월 14일

React Native の概念と動作原則に関する Seoyong Lee の洞察力に富んだ記事は、効率的なクロスプラットフォーム開発に対するフレームワークの可能性を強調しています。 React Native の利点を活用しようとしている企業にとって、適切な開発パートナーを見つけることは非常に重要です。
HireMobileDevelopers は、クライアントを一流の React Native 開発者と結び付けます。リソース リンクはこちら https://www.hiremobiledevelopers.com/hire-react-native-developers

답글 달기