Skip to main content

State of React Native 2018

· 10 min read
Sophie Alpert
Engineering Manager on React at Facebook

React Native의 최신 상태에 대해 업데이트를 공유한 지 꽤 시간이 지났다.

Facebook에서는 이전보다 더 많은 프로젝트에서 React Native를 사용하고 있다. 가장 인기 있는 제품 중 하나는 매월 8억 명이 사용하는 앱의 최상위 탭 중 하나인 Marketplace다. 2015년에 생성된 이후, Marketplace는 앱의 다양한 부분에 걸쳐 100개가 넘는 전체 화면 뷰를 포함해 모두 React Native로 구축되었다.

또한 앱의 새로운 부분에서도 React Native를 활용하고 있다. 지난달 F8 키노트를 본 사람이라면 Blood Donations, Crisis Response, Privacy Shortcuts, Wellness Checks 등을 기억할 것이다. 이 모든 최신 기능이 React Native로 만들어졌다. 메인 Facebook 앱 외부 프로젝트에서도 React Native를 사용한다. 새로운 Oculus Go VR 헤드셋에는 React Native로 완전히 구축된 컴패니언 모바일 앱이 포함되어 있으며, 헤드셋 자체에서도 React VR이 다양한 경험을 제공한다.

당연히 앱을 구축하기 위해 다른 기술들도 많이 사용한다. LithoComponentKit는 앱에서 광범위하게 사용하는 두 라이브러리다. 둘 다 네이티브 화면을 구축하기 위해 React와 유사한 컴포넌트 API를 제공한다. React Native가 다른 모든 기술을 대체하는 것이 목표는 아니었다. 우리는 React Native 자체를 개선하는 데 집중하지만, 다른 팀들이 React Native의 아이디어를 차용해 즉시 리로드와 같은 기능을 비자바스크립트 코드에도 적용하는 것을 보는 것을 좋아한다.

아키텍처

2013년 React Native 프로젝트를 시작할 때, 우리는 JavaScript와 네이티브 사이에 단일 "브릿지"를 설계했다. 이 브릿지는 비동기적이고 직렬화 가능하며 일괄 처리되는 특징을 가졌다. React DOM이 React 상태 업데이트를 document.createElement(attrs).appendChild()와 같은 DOM API에 대한 명령형 호출로 변환하는 것처럼, React Native는 [["createView", attrs], ["manageChildren", ...]]과 같이 수행할 뮤테이션 목록을 담은 단일 JSON 메시지를 반환하도록 설계했다. 우리는 이 시스템이 동기 응답을 받는 데 의존하지 않도록 설계했고, 목록에 있는 모든 것이 JSON으로 완전히 직렬화될 수 있도록 했다. 이는 우리에게 유연성을 제공하기 위한 선택이었다. 이 아키텍처 위에서, WebSocket 연결을 통해 모든 JavaScript 코드를 비동기적으로 실행하는 Chrome 디버깅과 같은 도구를 구축할 수 있었다.

지난 5년 동안, 이러한 초기 설계 원칙이 일부 기능 구현을 어렵게 만든다는 사실을 발견했다. 비동기 브릿지는 JavaScript 로직을 동기 응답을 기대하는 많은 네이티브 API와 직접 통합할 수 없게 한다. 네이티브 호출을 큐에 넣는 일괄 처리 브릿지는 React Native 앱이 네이티브로 구현된 함수를 호출하기 어렵게 만든다. 직렬화 가능한 브릿지는 두 세계 사이에서 메모리를 직접 공유하는 대신 불필요한 복사를 유발한다. React Native로 완전히 구축된 앱의 경우, 이러한 제약은 대체로 감내할 만하다. 하지만 React Native와 기존 앱 코드 간의 복잡한 통합이 필요한 앱에서는 불편함을 초래한다.

우리는 React Native를 대규모로 재구성하여 프레임워크를 더 유연하게 만들고, 하이브리드 JavaScript/네이티브 앱에서 네이티브 인프라와 더 잘 통합할 수 있도록 하고 있다. 이 프로젝트를 통해 지난 5년간 배운 교훈을 적용하고, 점진적으로 더 현대적인 아키텍처로 전환할 계획이다. React Native의 내부를 대부분 재작성하고 있지만, 대부분의 변경 사항은 내부적으로만 이루어진다. 기존 React Native 앱은 거의 또는 전혀 변경 없이 계속 작동할 것이다.

React Native를 더 가볍게 만들고 기존 네이티브 앱에 더 잘 통합하기 위해, 이 재구성은 세 가지 주요 내부 변경을 포함한다. 첫째, 스레딩 모델을 변경한다. 각 UI 업데이트가 세 개의 다른 스레드에서 작업을 수행해야 하는 대신, 높은 우선순위 업데이트를 위해 모든 스레드에서 JavaScript를 동기적으로 호출할 수 있게 하면서도, 낮은 우선순위 작업은 메인 스레드에서 벗어나 반응성을 유지할 수 있도록 한다. 둘째, 비동기 렌더링 기능을 React Native에 통합하여 여러 렌더링 우선순위를 허용하고 비동기 데이터 처리를 단순화한다. 마지막으로, 브릿지를 더 빠르고 가볍게 단순화한다. 네이티브와 JavaScript 간의 직접 호출은 더 효율적이며, 크로스 언어 스택 트레이스와 같은 디버깅 도구를 더 쉽게 구축할 수 있게 한다.

이러한 변경이 완료되면, 더 긴밀한 통합이 가능해진다. 현재는 복잡한 해킹 없이는 네이티브 네비게이션 및 제스처 처리나 UICollectionView, RecyclerView와 같은 네이티브 컴포넌트를 통합할 수 없다. 스레딩 모델 변경 후에는 이러한 기능을 쉽게 구축할 수 있을 것이다.

이 작업이 완료에 가까워지면 올해 안에 더 자세한 내용을 공개할 예정이다.

커뮤니티

페이스북 내부 커뮤니티와 함께, 우리는 페이스북 외부에서도 활발한 React Native 사용자와 기여자들을 보유하고 있다는 점을 자랑스럽게 생각한다. 우리는 React Native 사용자에게 더 나은 서비스를 제공하고, 프로젝트에 기여하기 쉽게 만드는 방식으로 React Native 커뮤니티를 더욱 지원하고 싶다.

우리의 아키텍처 변경이 React Native가 다른 네이티브 인프라와 더 깔끔하게 상호작용하도록 돕는 것처럼, React Native는 JavaScript 생태계에 더 잘 맞도록 JavaScript 측면에서 더 가벼워져야 한다. 이는 VM과 번들러를 교체 가능하게 만드는 것을 포함한다. 우리는 주요 변경 사항의 속도가 따라가기 어려울 수 있다는 것을 알고 있으므로, 주요 릴리즈를 줄이는 방법을 모색하고 싶다. 마지막으로, 일부 팀이 시작 최적화와 같은 주제에서 더 철저한 문서를 원한다는 것을 알고 있으며, 우리의 전문 지식이 아직 문서화되지 않은 부분이 있다. 이러한 변화들이 올해 중에 이루어질 것으로 기대해도 좋다.

React Native를 사용한다면, 여러분은 우리 커뮤니티의 일원이다. React Native를 더 나은 도구로 만들기 위해 우리에게 계속 의견을 알려주길 바란다.

React Native는 모바일 개발자의 도구 상자 중 하나일 뿐이지만, 우리는 이 도구를 강력히 믿고 있다. 그리고 우리는 지난 한 해 동안 500명 이상의 기여자가 2500개 이상의 커밋을 통해 매일 더 나은 도구로 만들고 있다.