Tech

Flutter가 React Native보다 낫습니다

Flutter와 React Native는 가장 많이 사용 되는 멀티플랫폼 모바일 앱 프레임워크입니다.

2022-05-09 Jimmy Lee

… 중요하지 않은 영역에서만요.

이 글은 원작자 Jamon Holmgren의 허락하에 원문 “Flutter is better than React Native*”를 번역한 글입니다.

Artwork by Jenna Fucci

Flutter와 React Native는 가장 많이 사용 되는 멀티플랫폼 모바일 앱 프레임워크입니다. 자연스럽게 경쟁자가 되었죠. 멀티플랫폼 앱은 개발자들의 격렬한 논쟁 끝에 결국 둘 중 하나를 사용하여 출시 됩니다.

그럼 어떤 게 더 나을까요?

현명한 시니어 엔지니어들이 건방지게 웃으며 말하는 대답은 다음과 같습니다: “그건 상황에 따라 달라요. 둘 다 장단점이 있고 결국 트레이드 오프(Trade Off)죠”

하지만 만족스러운 대답은 아닙니다. 마치 최고의 축구 선수는 “포지션에 따라 다르다”라고 말하는 것과 같습니다. 아무짝에도 쓸모가 없죠.

자, 그럼 왜 Flutter가 React Native보다 (중요하지 않은 영역에서) 더 나은지에 대해 이야기해 봅시다.

뭣이 중헌디

우리는 그다지 중요하지 않은 모든 것에 대해 이야기할 수 있습니다: 성능, 개발자 경험, Dart vs JavaScript, 네이티브와의 통합, 표준 라이브러리 등등..

제목이 자극적이네요. 인정합니다. 하지만 이건 단순한 낚시글이 아니에요! 사실, 저는 이 글의 뒷 부분에서 더 미묘한 방식으로 대부분의 것들에 대해 더 깊이 파고들 겁니다.

이제 본론으로 들어갑시다. 어떤 게 중요 할까요?

정답은 React Native와 Flutter의 기술적 측면과 전혀 관련이 없습니다. 이런 건 일반적으로 모바일 개발자가 신경써야 할 부분이 아니죠.

하지만 다음 앱에 무엇을 사용할지 결정하는 사람들에게 중요한 것은 다음과 같습니다:

채용

개발자를 고용하는 것은 매우 어렵습니다. 개발자 급여는 올랐지만 공급은 여전히 부족합니다. 당신의 회사에서 일하고 싶어 하는 괜찮은 개발자를 찾는 것은 정말 어려운 일입니다.

Flutter 개발자들은 열정적이고 수준이 높습니다. — 이건 Flutter 개발 커뮤니티의 어두운 면이 아닙니다! 그들은 단지… 수가 많지 않습니다. Dart 개발자를 끌어낼 거대한 풀은 존재하지 않습니다. 아마 개발자를 고용할 때마다 학습시켜야 할 겁니다.

반면에 React Native 개발자는 방대한 풀을 보유하고 있는데 그건 바로 JavaScript 커뮤니티입니다. JavaScript(및 TypeScript)는 단연 세계에서 가장 인기 있는 프로그래밍 언어이며 여전히 빠르게 성장하고 있습니다. React Native를 지원하는 React.js는 틀림없이 세계에서 가장 큰(가장 큰 것은 아니지만) 코딩 프레임워크 중 하나입니다. 여전히 고용하기 어렵지만 끌어낼 개발자 풀은 Flutter보다 훨씬 많습니다. React 개발자를 선택하여 합리적으로 생산적인 React Native 개발자로 만드는 것이 더 직관적인 프로세스입니다.

코드, 지식 및 개발자 공유

고용이 Flutter 또는 React Native를 사용하기로 결정하는 데 있어 가장 크고 가장 영향력 있는 부분이지만 제가 언급해야 할 또 다른 매우 중요한 부분이 있습니다. 바로 코드, 지식 및 개발자를 공유하는 것입니다.

좋은 코드보다 더 나은 게 뭘까요? 바로 코드량을 줄이는 겁니다. 코드를 줄이는 가장 좋은 방법 중 하나는 여러 앱 간에 코드를 공유하는 겁니다. 초기 개발 시간을 단축하고 장기적으로 유지 보수를 단순화할 수 있습니다.

이미 당신의 회사의 웹사이트, 웹 앱, 서버 등에서 React.js 또는 최소한 JavaScript를 사용하고 있을 가능성이 있습니다. React.js 앱, 노드 서버 등 간에 코드를 공유할 수 있다는 것은 React Native의 엄청난 초능력이며 Flutter는 이 부분에서 꿔다 놓은 보릿자루마냥 영 맥을 못 추죠.

코드를 공유하는 것 외에도 웹, 백엔드, iOS 및 Android 팀 간에 지식을 공유할 수 있다는 것은 엄청난 이점입니다. 공통 위키, Slack 채널 등을 가질 수 있고 또한 온라인에는 React Native, React 및 JavaScript에 대한 수많은 자습서, 블로그 기사, StackOverflow Q&A 등이 있습니다.

물론 이러한 프로젝트 간에 실제 개발자를 공유할 수 있으며 거의 재교육을 받지 않고도 중요한 프로젝트의 인력을 늘릴 수 있습니다.

결국 React Native와 Flutter 중 하나를 선택할 때 이러한 절대적으로 중요한 요소를 지나치기는 어렵습니다.

다른 건요?

하지만… 성능은요? 개발자 경험은? 접근성, 서드파티 라이브러리 생태계 등은 어떤가요?

거의 모든 경우에 Flutter와 React Native는 막상막하입니다. Flutter는 일부 전투에서 이기고 React Native는 다른 전투에서 이깁니다. 특정 영역에서는 비등비등하기도 합니다.

이게 이 글의 전부입니다. 핵심을 다 얻으셨어요. 이제 그만 읽으셔도 됩니다.

좋습니다… 왜 아직도 읽고 있나요?

뭐라고요? 더 구체적인 걸 원해요? 자세하게?

Gant Laborde 는 저더러 멈출 때를 알라고 하더군요.

하지만 어쩔 수 없네요. 말하는 게 너무 좋아요.

더 깊이 들어가 봅시다.

개발자 경험(DX)

Flutter의 팀(일반적으로 Google)은 개발자 경험에 상당히 능숙합니다.

Flutter 개발을 위한 환경 설정은 일반적으로 React Native보다 쉽습니다. Flutter의 Hot Reload는 일반적으로 React Native의 Fast Refresh보다 더 잘 작동합니다. 뷰 트리를 디버깅, 프로파일링 및 검사하기 위한 정말 좋은 도구가 있습니다. 내장된 E2E 테스트는 React Native의 Detox보다 훨씬 낫습니다. Flutter의 CLI는 엄청납니다. flutter doctor명령은 정말 사랑스럽고 CLI에서 시뮬레이터와 에뮬레이터를 바로 관리할 수도 있습니다.

Mike’s tweet

Flutter는 기존 앱에서 flutter create를 실행하기만 하면 새 버전으로 모든 것을 다시 생성할 수 있기 때문에 버전 업그레이드 경험도 더 좋습니다.

반면에 React Native의 도구는 Flutter의 도구가 가지고 있는 세련미가 많이 부족했습니다. React Native의 업그레이드 경험은 더 고통스러운 측면 중 하나입니다. 지난 몇 년 동안 이 제품을 사용해 본 사람이라면 누구나 증명할 것입니다.

반면 React Native의 도구에는 Flutter의 도구가 가진 많은 세련미가 없습니다. 지난 몇 년 동안 React Native를 사용해 본 적이 있다면 React Native의 업그레이드 경험은 고통스러운 부분 중 하나라는 걸 누구나 인정할 겁니다.

지금은 꽤 개선되고 있습니다. 최근 React Native Radio 에피소드(RNR 227)에서 우리는 Microsoft의 몇 명의 개발자와 React Native의 도구 및 전반적인 개발자 경험을 개선하기 위해 수행 중인 작업에 대해 이야기했습니다.

덧붙여서, Expo는 React Native에서 개발자 경험을 크게 향상시키도록 설계되었으며 Expo Application Services를 사용하면 바닐라 React Native에서 할 수 있었던 거의 모든 것을 Expo에서 할 수 있습니다. Expo의 업그레이드 경험은 훌륭하고 통합 도구도 잘 작동합니다. 네이티브 코드를 직접 수정하지 않는 경우 Expo Go 앱은 컴파일하지 않고도 빌드를 다른 사람과 빠르게 공유할 수 있는 놀라운 방법입니다. Expo는 작지 않은 이점입니다!(당신이 그것을 사용한다면 말이죠)

TL;DR: Flutter 개발자 경험의 우위는 Flutter진영의 가장 강력한 주장 중 하나입니다. 리액트 네이티브는 따라잡고 있지만 아직 갈 길이 멉니다. (하지만 Expo가 큰 힘을 발휘하고 있습니다.)

성능

Flutter 및 React Native 만큼 복잡한 소프트웨어 프레임워크에서 성능을 비교하는 것은 훨씬 어렵습니다. Flutter와 React Native는 모두 대부분의 상황에서 “충분히 빠릅니다”, 유능한 개발자가 성능 최적화 수행했다면 더더욱 그렇습니다.

그러나 역사적으로 Flutter의 기본 성능은 React Native보다 우수했습니다. 그렇다고 하더라도 성능이 낮은 Flutter 앱성능이 높은 React Native 앱은 확실히 만들 수 있습니다.

성능 차이는 대부분 이번 봄에 출시될 새로운 아키텍처(네이티브와 JS 간의 동시 통신)가 대체할 비동기 React Native 브리지로 인한 것입니다. 또한 Hermes JS 엔진은 많은 주요 지표에서 성능을 향상시킵니다. 마지막으로 Skia(Flutter 에서 사용하는 렌더러)는 이제 React Native 에서도 제공됩니다. 즉, Flutter에서 사용하는 것과 동일한 React Native용 렌더러를 가질 수 있습니다. (부드러운 캔버스 성능 같은 것이 필요한 경우에)

TL;DR: Flutter는 성능면에서 (현재로서는) 약간 이기고 있지만 새로운 React Native 아키텍처의 출현으로 곧 그 격차가 해소될 것으로 기대됩니다.

일관된 UI 경험

Flutter는 Skia를 사용하여 UI를 렌더링하고 모든 플랫폼에서 모양과 느낌을 일관되게 유지합니다. 이를 통해 플랫폼의 기본 요소에 제약을 받지 않고 성능을 최적화하고 커스텀 UI를 만들 수 있습니다.

반면에 React Native는 iOS의 UIKit, Android의 Android 레이아웃 시스템, 웹의 DOM을 사용합니다. 즉, 매우 유사한 모양의 앱을 빌드 할 수 있지만 각 플랫폼 특색에 따라 조금씩 다른 모양을 하게 됩니다.

Flutter에 대한 한 가지 비판은 접근성, 글꼴 크기 조정 등과 같이 플랫폼이 이미 대부분 해결한 모든 종류의 것들을 다시 처음부터 만들어야 한다는 것입니다. 솔직히 그들은 이 일을 상당히 잘 해냈지만 이것은 React Native가 플랫폼을 통해 해결하는 문제들을 직접 구현해야 하는 것들 중 일부에 불과합니다.

Google 개발자가 일관된 경험이 더 이상 핵심 목표가 아니라고 말한 것(iOS 머테리얼 디자인 컴포넌트 프로젝트의 중단을 함께 이야기하며)은 주목할 가치가 있습니다. Flutter의 접근 방식과 잘 어울리지 않죠.

TL;DR: 플랫폼간 일관된 경험보다 사용자가 플랫폼별로 기대한 자연스러운 경험을 제공하는 것이 더 중요하다는 전제에 동의한다면 React Native가 더 낫습니다.

네이티브 통합

네이티브 플랫폼과 통합하는 것은 내가 방송에서 가장 좋아하는 것 중 하나입니다(내 Twitch 채널을 확인하고 팔로우해보세요!).

Flutter는 Dart 코드를 네이티브로 컴파일하고 플랫폼 채널이라고 부르는 네이티브 코드와의 매우 멋진 통합 모델을 가지고 있습니다. Swift 및 Kotlin으로 동기식 네이티브 호출을 작성할 수 있습니다. 이 부분에 대해서는 Flutter의 문서에 상세히 나와있습니다. 그리고 테스트하고 mock하는 데 필요한 모든 도구도 손쉽게 사용할 수 있습니다. 각 플랫폼에 대해 많은 템플릿을 얻을 수 있으며 스레딩에 대한 최고 수준의 지원을 제공합니다.

React Native의 경우에는 네이티브와 통합하는 데 약간의 학습 곡선이 있습니다. (이것이 내가 React Native Colo Loco를 만든 이유 중 하나입니다. 더 좋은 경험을 하기 위해서요!) React Native 브리지의 한계와 씨름해야 하는 것은 말할 것도 없습니다. 문서도 별로구요.

새로운 React Native 아키텍처가 브리지를 대체하고 동기식 네이티브 통합의 모든 이점을 React Native로 가져와 이러한 결함 중 일부를 완화한다는 점은 주목할 가치가 있습니다.

TL;DR: 두 플랫폼 모두 완전한 네이티브 통합 기능을 가지고 있지만 Flutter의 네이티브 통합 도구가 더 좋습니다.

i18n

국제화/현지화(i18n) 또한 중요하죠. Flutter는 i18n 지원이 내장되어 있습니다. React Native는 내장되어 있지 않지만 서드파티 i18n 지원이 요즘 꽤 좋아지고 있습니다.

Mazen Chami와 저는 최근에 RTL 언어 지원(아랍어)을 앱에 구현하는 라이브 방송을 진행 했습니다.

TL;DR: 승자가 없습니다 — 두 플랫폼 모두 i18n을 잘 지원합니다. (몇 가지 제한 사항이 있지만)

내장 네비게이션 (& more)

Flutter는 React Native보다 약간 더 “즉시 사용”할 수 있도록 설계되었으며 이것이 가장 분명하게 드러난 것 중 하나는 자체 네비게이션 솔루션이 제공된다는 점입니다.

네비게이션은 대부분의 프로그램에 매우 중요하기 때문에 핵심 프레임워크에 포함되는데 특히 알맞은 모듈입니다. 예를 들어 자체 라우터가 없는 Next.js를 상상해 보십시오. 아주.. 별로네요.

React Native는 훨씬 덜 편향적이며 네비게이션 솔루션을 자유롭게 선택할 수 있습니다. 많은 것이 있지만 가장 잘 지원되는 것은 (유감스러운 이름인) React NavigationReact Native Navigation 라이브러리입니다.

Flutter에는 테마 지원 등이 내장되어 있습니다. 매우 인기 있는 React Native boilerplate인 Ignite는 자체 테마 지원과 함께 제공되지만 바닐라 React Native에 테마가 내장되어 있지는 않습니다.

Flutter와 같은 내장 솔루션의 이점은 프레임워크의 각 버전과 잘 작동하도록 특별히 조정될 수 있다는 점입니다. 단점은 더 나은 패러다임이 등장할 때 공식적으로 지원되는 솔루션을 더 새롭고 더 나은 솔루션으로 교체하는 데 엄청나게 힘들 수 있다는 것입니다.

TL;DR: Flutter의 승리. 내비게이터가 내장된 것도 좋지만 React Native의 커뮤니티도 몇 가지 아주 좋은 옵션을 제공합니다.

웹 지원

Flutter 2는 웹 및 기타 플랫폼 지원을 발표했습니다(Robin Heinze와 제가 React Native Radio에서 리뷰했어요).

그러나 웹에 대한 그들의 접근 방식은 기본 DOM을 사용하는 것보다 “캔버스를 사용하여 그 위에 그리자”에 훨씬 가깝습니다. Sebastien Lorber는 이 Twitter 스레드에서 더 자세히 설명했습니다.

이 방식은 접근성 및 SEO 문제를 만들어냅니다. 또한 Flutter for web을 사용해야 하는데 쉽게 말해서 좋은 선택은 아닙니다.

Jamon’s tweet

Flutter가 HTML/CSS/DOM 버전을 제공한다는 점은 주목할 만 합니다. 캔버스 렌더러보다 덜 사용되지만 React.js의 발끝에도 미치지 못합니다.

반면에 React Native는 React Native for Web을 사용하든 React.js를 직접 사용하든 코드를 직접 공유할 수 있습니다. JavaScript/TypeScript 공유 서비스 및 모듈을 사용하여 많은 비즈니스 로직, 데이터 모델 등을 공유할 수 있으며 UI 구성 요소를 분할하거나 웹용 React Native를 사용하여 직접 공유할 수 있습니다. React.js는 웹용으로 특별히 설계되었으므로 웹용 Flutter와 달리 웹은 일급 객체입니다.

웹 지원을 포함한 Flutter에 대한 비평을 원한다면 해당 주제에 대한 Theo의 최근 YouTube 동영상과 Theo의 동영상에 대한 Luke Pighetti의 반응을 확인하세요. 여기에서 그는 Flutter 모바일에 대한 많은 Theo의 결론에는 동의하지 않지만 웹용 Flutter에 대해서는 일반적으로 동의합니다.

TL;DR: React Native의 분명한 승리. Flutter 2가 조금 노력하고 있지만 React Native는 웹에서 엄청난 우위를 점하고 있습니다. (뒤집힐 것 같지는 않네요)

서드파티 라이브러리

일반적인 React Native 앱에서는 원래 JavaScript 또는 React용으로 설계된 여러 라이브러리와 도구를 사용합니다. 그 중 일부는 axios, mobx, redux, lodash, ramda, eslint, babel, jest, prettier, react-devtools, typescript, npm 및 yarn을 포함합니다.

이들은 모두 웹 및 노드 개발자가 지속적으로 사용하는 라이브러리입니다. 이는 연합된 커뮤니티가 이러한 도구에 기여 및 개선할 수 있을 뿐만 아니라 (다시) 지식을 공유하고 서로를 도울 수 있음을 의미합니다.

반면 Flutter는 일반적으로 Flutter용 라이브러리를 사용합니다. 일부 타사 Dart 라이브러리를 사용할 수 있지만 해당 커뮤니티는 JavaScript보다 훨씬 작습니다.

그렇기는 하지만 Dart는 통합 포맷터, 테스트, 컴파일러, 분석기/린터 및 패키지 관리자와 함께 제공되며 타입 안전하고 null 안전한 언어라는 점에 주목할 만합니다. 이것은 Flutter와 Dart를 사용할 때 더 적은 수의 서드파티 라이브러리만으로도 충분할 수 있음을 의미합니다.

TL;DR: Flutter와 Dart에는 몇 가지 고품질 내장 도구가 있지만, Dart/Flutter와 같은 고립된 커뮤니티에서 JavaScript/React와 같은 강력한 생태계를 모방하는 것이 거의 불가능하기 때문에 서드파티 생태계는 React Native의 승리입니다.

사용하는 회사들

React Native는 이제 실로 여러기업들의 공동 작업이 되고있습니다. Meta/Facebook 외에도 Microsoft는 React Native 개발에 막대한 투자를 하고 있습니다. 코어 팀은 React Native의 다양한 측면에서 Microsoft 개발자와 지속적으로 협력합니다. 그들은 Microsoft에서 React Native로 많은 앱을 다시 작성하고 이를 위한 수많은 도구와 라이브러리를 구축하고 있습니다. 사실, 그들은 심지어 최근에 Windows의 기본 설정 앱이 (부분적으로) React Native로 작성되었다고 발표했습니다!

Meta(Facebook & Instagram) 와 Microsoft 외에도 React Native는 Coinbase, Shopify, Mercari, Discord, Pinterest, Tesla, Walmart, Wix, Salesforce, NFL, MLS, Uber Eats 등과 같은 대기업에서도 광범위하게 사용됩니다.

Flutter는 여러 전과가 있는 Google에서 주로 지원합니다. Toyota, eBay 및 Alibaba를 포함하여 Flutter를 사용하는 다른 회사가 있지만 대부분의 개발은 Google에서 주도합니다.

그렇긴 해도 Flutter는 오픈 소스에서 개발을 훌륭하게 수행했으며 지속적인 커뮤니티 참여와 피드백에 의해 주도되었습니다. 이는 Meta/Facebook이 필요로 하는 것을 우선으로 하고, 최종적으로 외부에서 이용할 수 있게 되기 전에 비공개로 진행되는 React Native의 일반적인 느낌과는 다릅니다. React Native의 핵심 팀은 최근 이 프로세스를 보다 커뮤니티 중심적으로 만들기 위해 많은 노력을 기울이고 있습니다.

TL;DR: React Native의 승리입니다. 한 문장으로 요약하기 어려운 몇 가지 뉘앙스와 함께.

동적 업데이트 (Code Push 등)

모든 프로젝트에 적용되는 것은 아니지만 App Store와 Play Store에 제출하고 승인 절차를 거치지 않고도 동적 업데이트를 수행할 수 있는 기능 때문에 React Native를 사용하는 회사가 많다고 들었습니다. 이것은 Flutter의 로드맵에 없습니다.

TL;DR: React Native의 승리

그렇다면 Flutter보다 React Native를 사용해야 할까요?

글쎄요… 상황에 따라 다릅니다. 둘 다 장단점이 있기 때문에 결국 트레이드오프에 대한 결정입니다. (웃음)

이 주제에 대해 수천 개의 단어가 쏟아져 나왔음에도 불구하고 여기에 언급된 차이점조차도 실제로 그렇게 크거나 명백한 것은 아닙니다.

앞서 언급했듯이 고용할 개발자 풀을 훨씬 더 많이 확보하는 것이 주요 고려 사항입니다. React Native는 JavaScript/TypeScript를 사용하는 웹 및 백엔드 개발자가 이미 있고 특히 React를 이미 사용하고 있는 경우 특히 매력적입니다.

Java 또는 Android 개발자 출신(Java/Kotlin에서 온 경우 Dart가 더 쉽습니다) 이거나 일관된 Fluid UI가 필요한 경우 Flutter가 확실히 좋은 옵션이 될 수 있습니다. 고용하기가 더 어려울 수 있지만 Flutter의 뛰어난 개발자 경험과 성능은 꽤 좋은 보상입니다.

결국, “상황에 따라 달라요” 변명이 정말 맞는 말입니다. 그러나 — 적어도 이제는 어떤 여러가지 트레이드오프가 있는지 알게 되었습니다!

다른 생각들

논란이 되는 주장을 하는 모든 글은 필연적으로 철저히 검사받게 될 겁니다. 이것은 제 관점이며 제가 React Native 컨설팅을 소유하고 있고 React Native 핵심 팀과 함께 일하고 있다는 점을 감안할 때 편견이 없다고 주장하지 않겠습니다. 그러나 저는 상당한 양의 연구를 수행했고 두 가지 모두를 고려하는 많은 회사와 협력했으며 여러 Flutter 개발자로부터 이 글에 대한 피드백을 받았습니다. 그들이 내 의견과 결론에 동의하지 않을 수 있지만, 적절한 피드백은 확실히 반영했습니다. 나는 최대한 공정하게 하고 싶습니다.

또한 Dart vs TypeScript의 구문 또는 JSX vs Dart의 뷰 계층 구조와 같은 미적 요소에 초점을 맞추지 않으려고 노력했습니다. 우리는 하루 종일 어느 것이 더 나은지에 대해 논쟁할 수 있지만 이는 순전히 개인적인 취향이며 프레임워크의 사용성에 크게 영향을 미치지 않습니다. Dart와 JavaScript/TypeScript 사이에 차이점이 없다는 것은 아닙니다. 하지만 특정 트레이드오프를 해결하려면 2,000단어 짜리 글이 더 필요할 것이며, 이는 여기에서 하려는 일의 범위를 벗어납니다.

Jimmy Lee Soomgo Mobile Engineer
숨고의 성장을 위해 열심히 고민하며 노력하고 있습니다.