리액트네이티브 vs 플러터

Kyoungmoon Kim·2022년 12월 29일
4

인기

크로스플랫폼 앱 개발 기술에 대한 인기는 나날이 높아지고 있으며, 리액트 네이티브와 플러터가 가장 영향력 있는 프레임워크입니다.

리액트 네이티브는 2015년에 출시되었고 플러터는 2018년에 출시되었습니다. 따라서 리액트 네이티브가 플러터보다 큰 커뮤니티를 가지고 있고 더 성숙한 개발 언어이며 든든한 커뮤니티 지원을 받을 수 있습니다. 하지만 플러터 2.0의 출시와 함께, 플러터의 약진이 기대되고 있습니다.

아래 구글 트렌드를 보면 플러터의 인기가 나날이 높아지고 있다는 것을 확인할 수 있습니다.

파란색: 플루터
빨간색: 리액트 네이티브

언어의 차이

Flutter: Dart
React Native: JavaScript
일단 2가지 컴파일 방식의 개념에 대해 간단히 짚고 넘어가자.

JIT — “Just in Time”. 컴파일러가 코드를 번역하고, JIT이 런타임중에 코드를 선택적으로 최적화 한다. 빠른 스타트업 속도를 보여주지만 준비시간(warm-up)이 걸리고 첫번째 실행해서는 퍼포먼스가 다소 낮지만 실행이 반복될수록 점차 향상된다. 하지만 상황에 따라 예측불가한 퍼포먼스를 보여준다.

AOT — “Ahead of time”. 컴파일과 최적화가 실행 전에 이루어진다. 컴파일 시간은 오래걸리지만 최적화가 완전히 이루어졌기 때문에 전반적으로 예측가능한 성능을 보여주고 특히 애니메이션과 같이 무거운 작업에서 좋은 퍼포먼스를 보여준다.

그렇다면, React Native와 Flutter가 어떻게 다를까? 이 두 프레임워크의 언어를 기반으로 전반적인 특징들을 정리해보았다.

리액트 네이티브는 자바스크립트 언어를 사용한다. 원래 리액트(React)가 웹 어플리케이션 개발용으로 먼저 개발되었고 리액트 네이티브가 차후 네이티브 플랫폼을 타겟으로하여 만들어졌는데 기존의 비즈니스 로직과 많은 모듈들을 활용하기 위해서는 자바스크립트를 사용해야 했다.

그렇다면 React Native 가 자바스크립트 코드를 네이티브 플랫폼에서 실행되기 위한 전반적인 프로세스에 관하여 간단히 알아보자: React Native는 자바스크립코드를 번들화해서 그것을 디바이스로 전송한다. 그 다음 네이티브 플랫폼상에서 번들화된 명령어를 수행하여 브릿지를 통해 UI렌더링을 실행할것을 React Native 에게 명령한다. 여기서 브릿지는 자바스크립트가 네이티브 플랫폼에서 그에 맞는 형태로 실행 될 수 있도록 도와주는 인터페이스 역할을 담당한다. (iOS — Objective-C / Android — Java)

자바스크립트는 interpreted 또는 JIT 컴파일 언어이다. 동적(dynamic) 타입의 언어이기 때문에 AOT 컴파일에는 적합하지 않다. iOS의 경우 자바스크립트 코어(JavaScriptCore)라는 자바스크립트 엔진을 제공하는데 이는 Safari 환경에서 JIT을 지원하고 안드로이드는 Chrome V8이 있다. 이러한 엔진은 자바스크립트 코드와 네이티브 플랫폼간의 좋은 성능을 보여주는데 그럼에도 불구하고 React Native는 네이티브 플랫폼 상에서 제한적인 면들이 있다. 예를들어, iOS는 보안상의 이유로 릴리즈 환경에서 JavascriptCore의 JIT을 사용할 수 없다. 또한 Javascript가 AOT에 부적합하다는 것은 무거운 작업에서 예측가능한 퍼포먼스를 보장해주지 못한다.

플러터는 Dart언어를 사용한다. Dart는 자바스크립트에 비해 유연하다. 이 언어가 자바스크립트와 달리 갖는 특별한 점은 정적 타입 또는 다이나믹 타입 성격을 유동적으로 지닐 수 있다는 것이다. 그러므로 다트는 JIT뿐만 아니라 AOT 또한 지원할 수 있다. 게다가, Dart는 플러터를 개발한 구글에서 만든 언어이기 때문에 구글은 필요와 상황에 맞게 언어를 조정할 수 있다. 그리고 실제로 AOT가 Dart 2부터 도입되었다. 다트의 이러한 예외적인 성격은 iOS와 안드로이드 뿐만 아니라 다른 플랫폼까지도 확장될 수 있다는 가능성을 보여준다.

스타일링

리액트 네이티브는 HTML과 비슷한 React 컴포넌트 JSX 문법을 사용한다. 그리고 컴포넌트의 스타일 속성은 css와 유사한 StyleSheet을 통해 부여한다. 아래의 코드는 리액트 네이티브에서 간단한 텍스트 컴포넌트를 렌더링 할때 쓰이는 스타일 적용 방식을 보여준다.

Flutter 에서 스타일링 방식은 위젯을 통해 이루어진다. 그 차이를 보여주기 위해 코드의 일부를 첨부했다. 보이다시피 padding, margin, alignment나 다른 스타일 속성값들이 위젯으로 정의되어 있다. 스타일을 적용하고싶은 위젯을 스타일 위젯으로 감싸는 방식으로 스타일을 부여한다.

‘Padding’ 은 속성값과 함께 그 값을 부여할 child 위젯을 갖고있다. ‘Column’ 은 수직형 레이아웃과 기본적으로 Flex 위젯을 상속함으로써 flex 속성을 지니고, 다수의 child 위젯을 가질 수 있다.

위의 두 예시 모두 비슷한 형태의 텍스트 뷰를 렌더링한다. Flutter의 코드가 React Native 방식보다 좀더 장황해 보인다. 하지만 이부분은 지극히 개발자의 취향차이인데, 만약 웹 개발에 익숙하다면 React Native 방식이 좀 더 친근하게 보이겠다.

러닝 커브

리액트 네이티브는 대부분의 개발자에게 익숙한 자바스크립트 기반의 JSC를 수년째 사용하고 있기 때문에 매우 쉽게 익힐 수 있습니다. 대부분의 리액트 개발자는 역시 별다른 학습 없이 모바일 애플리케이션 개발을 시작할 수 있습니다.

하지만 플러터는 대부분의 개발자에게 생소한 다트(Dart) 언어를 사용하기 때문에 플러터를 익히기 위해서는 이 언어를 배워야 한다는 진입장벽이 있습니다.

성능

플러터는 구글에서 개발한 다트 프레임워크를 사용하고 있으며, 이 언어는 skia2 그래픽 라이브러리와 C/C++ 엔진을 사용합니다. C/C++ 엔진을 사용한다는 점에서부터 이미 그 차이를 예상할 수 있습니다. 이러한 언어적 특성으로 인해 네이티브 플랫폼과 프레임워크 사이에 추가적인 커뮤니케이션과 변환이 필요하지 않으며 더 빠른 성능을 보장합니다. C/C++ 로우레벨(low-level) 언어3로 분류되며 컴파일 시 기계 코드에 더 가깝기 때문에 플러터는 보다 빠르고 부드럽게 동작합니다.

반면 리액트 네이티브 아키텍처는 JS Bridge로 불리는 자바스크립트 런타임 환견을 기반으로 하며 페이스북에서 개발한 FLUX 아키텍처를 사용합니다. JS Bridge는 자바스크립트 모듈과 네이티브 플랫폼 간의 커뮤니케이션을 생성하고 런타임 중에 코드를 네이티브 코드로 컴파일합니다. 이 때문에 성능에 영향을 주는 CPU와 메모리의 사용량이 더 높습니다.

하지만 리액트 커뮤니티와 페이스북은 리액트 네이티브의 성능을 향상시키기 위해 열심히 노력하고 있으며, 리액트 네이티브 커뮤니티에서 많은 성능 최적화 작업이 진행중 입니다.

페이스북은 최근 안드로이드에서 리액트 네이티브 모바일 앱의 성능을 개선하기 위해 헤르메스(Hermes)라는 새로운 자바스크립트 엔진을 발표했습니다. 앱의 렌더링 시간을 최적화하고 메모리와 CPU를 덜 사용하며 앱 크기 또한 작아집니다.

커뮤니티 지원

앞서 언급했듯이 리액트 네이티브는 페이스북이 2015년에 출시했으며 플러터보다 훨씬 성숙한 프레임워크입니다. 그동안 리액트 네이티브 커뮤니티는 크게 성장했고 리액트 네이티브의 성공에 지대한 공헌을 했습니다. 커뮤니티에서 개발한 모든 npm4 패키지를 쉽게 찾아 사용할 수 있습니다. 만약 어딘가에 문제가 있다면 커뮤니티에 이미 그 해답이 있는 경우가 대부분입니다.

플러터의 경우 구글이 2018년에 출시한 프레임워크로 커뮤니티의 규모가 네이티브에 비해 작습니다. 아직 리액트 네이티브의 성숙도에는 미치지 못함, 종종 pub5에서 원하는 패키지를 찾지 못할 수도 있습니다. 그러나 플러터 2.0이 출시된다면 점유율이 증가하며 이러한 상황은 바뀔 수 있습니다. 점점 더 많은 개발자가 리액트 네이티브보다 좋은 성능과 플랫폼 호환성을 갖춘 플러터를 선택하고 있습니다.

크로스 플랫폼

모든 기업과 개발자는 단일 코드베이스에서 앱스토어와 구글 플레이 모두에서 동작하는 앱을 만들고 싶어합니다. 플러터와 리액트 네이티브는 이러한 시장을 양분하고 있습니다.

다음과 같은 경우 크로스플랫폼 개발을 채택합니다.

· 단기간에 앱을 개발하고 싶을 경우

· 네이티브 앱의 제약사항을 극복하기 위해

· 시장에 변화에 맞춰 빠르게 앱을 수정해야 할 때

플러터 코드는 자바스크립트로 컴파일 할 수 있습니다. 따라서 하나의 코드베이스를 안드로이드, iOS, 웹에서 동일하게 사용할 수 있습니다. 리액트 네이티브는 iOS와 안드로이드 애플리케이션에서 네이티브 방식으로 렌더링되는 실제 코드를 작성할 수 있는 프레임워크입니다.

최근 출시된 플러터 2.0 에서는, 동일한 코드베이스를 사용하여 iOS, 안드로이드, 윈도우, macOS, 리눅스의 5가지 운영 체제에서 동작하는 네이티브 앱을 개발할 수 있습니다. 또한, 크롬, 파이어폭스, 사파리, 엣지와 같은 대부분의 최신 브라우저에서 실행되는 웹 앱을 만들 수 있습니다. 심지어 자동차, TV, 스마트 가전 제품에도 플러터 앱을 탑재할 수 있습니다.
크로스 플랫폼 개발 앱은 단일 코드베이스로 만들 수 있으며 iPhone 및 Android 운영 체제에서 거의 동일하게 작동합니다.

테스트

테스트는 최소한의 시간과 노력으로 코드의 원활한 동작을 보장하기 위해 매우 중요합니다.

리액트 네이티브는 통합 및 UI 수준의 테스트에 대한 공식 지원이 없스빈다. RN 앱을 테스트하는 데 사용할 수 있는 유닛 테스트 수준의 프레임워크는 몇 개가 전부입니다. 개발자는 Appium 또는 Detox와 같은 써드파티 도구를 사용해야 합니다. 또한 iOS 앱을 앱스토어에 자동으로 배포할 수 없습니다. 이 때문에, 리액트 네이티브에서는 Xcode를 통해 앱스토어에 수동으로 앱을 배포해야 합니다.

반면, 플러터는 탁월한 테스트 자동화를 지원합니다. 앱에 대한 유닛, 위젯, 통합 테스트를 수행할 수 있는 기능을 제공하며 이에 대해 상세한 공식 문서를 제공합니다. 또한 플레이 스토어와 앱 스토어에서 안드로이드와 iOS 용 앱을 빌드하고 출시하기 위한 문서도 제공합니다. 뿐만 아니라 배포 프로세스에 대해서도 훌륭한 공식 문서를 제공합니다.

애플리케이션 크기

프레임워크의 선택은 앱의 크기에 큰 영향을 미치며, 앱의 크기는 사용자에게 민감한 부분입니다.

간단한 리액트 네이티브 앱의 크기는 7MB이지만 기본적인 디펜던시(dependency)가 추가되면 최대 13.4MB까지 증가합니다. 코드 스플리팅(Code Splitting)을 사용하면 네이티브와 외부 라이브러리를 나누어 빌드하기 때문에 앱 크기를 줄일 수 있습니다. 여기에 헤르메스 엔진을 사용하면 크기를 더 줄이는 것이 가능합니다.

반면, 플러터에서 만든 간단한 Hello World 앱의 크기는 7.5MB입니다. 플러터 앱의 크기는 다트 가상머신과 C/C++ 엔진의 영향을 받습니다. 그러나 플러터에서도 -split-debug-info 와 같은 특정 태그를 사용하면 코드 크기를 줄일 수 있습니다.

적용 사례

리액트 네이티브

· 페이스북 – 심플한 네비게이션을 갖춘 강력하고 사용자 친화적인 모바일 UI를 개발했습니다.

· 월마트 – 네이티브와 동일한 부드러움을 자랑하는 인앱 애니메이션을 구현해 사용자 경험을 개선했습니다.

· 블룸버그 – 자동 코드 리프레시 기능을 통해 유기적이고 사용하기 쉬운 개인화 콘텐츠를 제공합니다.

· 인스타그램 – 별도의 네비게이션을 개발하지 않고 WebView 형태로 푸시 알림을 구현했습니다.

· 사운드클라우드(SoundCloud) – iOS와 안드로이드에 동시 배포가 가능해지며 빠른 업데이트와 패치가 가능해졌습니다.

· 윅스(Wix) – 수정 가능한 네비게이션과 스크린 옵션 개발에 적용하여 빠른 개발과 민첩성을 확보했습니다.

플러터

· 구글 애즈 – iOS와 안드로이드에 일관된 사용자 경험을 제공하기 위해 다트 패키지, 파이어베이스 애드몹(Firebase AdMob) 플러그인, 플러터의 스태틱 유틸리티 클래스를 사용했습니다.

· 텐센트 – 5명 미만의 개발자가 다중 플랫폼에서 지원을 사용자 간에 연결되고 공유되는 사용자 경험을 구축했습니다.

· 알리바바 – 단일 코드베이스로 모든 애플리케이션에서 높은 FPS를 제공하는 단일 탭 네비게이션 경험을 구축했습니다.

· 이베이 – 플러터와 파이어베이스(Firebase)를 통합하여 eBay Motors을 위한 autoML을 개발했으며, 이를 통해 자사에 특화된 복잡하고 강력한 최신 AI 기능을 누리고 있습니다.

· BMW – 앱 관리에 flutter_bloc을 사용하여 고성능 사용자 인터페이스를 개발했습니다.

· 리플렉틀리(Reflectly) – 리액트 네이티브에서 플러터로 마이그레이션 했으며, StreamBuilder 위젯을 통해 고품질 데이터 이벤트를 생성함으로써 데이터 동기화를 개선했습니다.

결론

리액트 네이티브는 간단한 크로스플랫폼 애플리케이션을 만드는 데 적합하고, Flutter는 MVP 애플리케이션을 만드는 데 탁월합니다.

크로스플랫폼은 빠른 개발과 시장 출시가 가능하게 만들어줍니다. 또한, 써드파티 라이브러리를 활용하여 더욱 효율적으로 앱을 개발할 수 있습니다.

아래에 해당된다면 리액트 네이티브를 선택하세요.

· 크로스플랫폼 모듈을 통해 현재 애플리케이션을 확장하고 싶습니다.

· 아주 가벼운 네이티브 애플리케이션을 개발하는 것이 목표입니다.

· 비동기 빌드와 반응형 UI로 애플리케이션을 만들고 싶습니다.

· 프로젝트에 투자할 시간이 충분합니다.

아래에 해당된다면 리액트 플러터를 선택하세요.

· 개발하려는 앱이 네이티브의 모든 기능을 필요로 하지 않는 경우

· 예산과 납기 일정이 촉박합니다.

· 더 빨리 개발하여 빠르게 시장에 출시하고 싶습니다.

· 60FPS ~ 120FPS의 성능이 필요합니다.

· 위젯과 약간의 테스트만으로도 커스텀 UI를 만들고 싶습니다.

출처
https://blog.wishket.com/%ED%94%8C%EB%9F%AC%ED%84%B0-vs-%EB%A6%AC%EC%95%A1%ED%8A%B8-%EB%84%A4%EC%9D%B4%ED%8B%B0%EB%B8%8C-2021%EB%85%84%EC%9D%98-%EC%8A%B9%EC%9E%90%EB%8A%94/

https://medium.com/fm-stories/react-native-%EC%99%80-flutter%EB%8A%94-%EC%96%B4%EB%96%BB%EA%B2%8C-%EB%8B%A4%EB%A5%BC%EA%B9%8C-e9ea4a81b6d5

profile
프론트 개발 공부를 정리한 블로그입니다.

1개의 댓글

comment-user-thumbnail
2024년 2월 2일

Flutter를 꼭 모바일을 만드는 데만 쓰는 게 아니기 때문에,
Flutter가 RN을 앞선다고 보기 어려운 것 같습니다.

답글 달기