FlutterとReact Native(とXamarin)の正しい(?)比較 

# はじめに

クロスプラットフォーム開発フレームワークの比較はとかく機能要素の議論になりがちですが、星取表での比較が正しい評価に繋がっていないように感じます。開発・導入動機や設計コンセプトやがより重要で、それが非機能による現時点の使い勝手や機能・非機能の将来性に多大な影響を与えていると感じるからです。

本ブログでは各フレームワークの開発・導入動機やコンセプトを中心にFlutter、React Native、Xamarinを比較したいと思います。

# 比較・検討
##  一言で言うと
| Flutter | React Native | Xamarin |
|----|----|----|
|ネイティブモバイルSDKの再発明|モバイルアプリ開発へのReactによるWebフロントエンド開発手法の導入|モバイルアプリ開発へのC#の導入|

以下ではそう思った理由を含めて比較します。

## フレームワーク開発の究極の動機
| Flutter | React Native | Xamarin |
|----|----|----|
| 技術力誇示・企業ブランド向上 | 技術力誇示・企業ブランド向上 | 企業ブランド向上 |
| アプリ社内開発の効率化| アプリ社内開発の効率化 |  |
| フレームワークデバッグリソースの外部調達 | フレームワークデバッグリソースの外部調達 |  |
| モバイルアプリ開発業界の活性化 |  | |

ここは[React Native vs Flutter - Which to Learn? - YouTube](https://youtu.be/tSyXb0sHBoE?t=3m56s"React Native vs Flutter - Which to Learn? - YouTube")を参考にプラスアルファしています。

XamarinのXamarin社にとっての存在意義はフレームワーク販売による直接的収益でした。
Xamarin社をマイクロソフトが買収したのはXamarinかなり成熟してからだったので、買収時点のマイクロソフトにとってのXamarinの存在意義は企業ブランド向上がメインだと感じてます。

FacebookがReact Nativeの開発に着手した直接の動機は「[InfoQ: Facebook:「HTML5に賭けたのは間違い」発言の技術的な理由と反応](https://www.infoq.com/jp/news/2012/09/Facebook-HTML5-Native "Facebook:「HTML5に賭けたのは間違い」発言の技術的な理由と反応")」でしょう。それをわざわざOSSで公開するのは、アプリ開発者コミュニティーによるReact Nativeのデバッグと技術力誇示による企業ブランド向上が目的だと思います。

GoogleがFlutterの開発に着手した最初の動機も社内開発の効率化でしょう。特に、Material Designの実装を素のAndroid SDKで行うのは大変なものと想像します。実際、AndroidにおけるMaterial Designの実装はAndroid SDK版よりもFlutter版の方が進んでいるそうです。また、Googleの事業にとって最もクリティカルな外部向けモバイルアプリであるAdWordsの広告主向けアプリでFlutterをいち早く採用していることからも、その動機が見て取れます。
Flutterに特有の開発動機はモバイルアプリ開発業界を活性化したいというところでしょう。モバイルを含めたネット広告ビジネスに収益の基盤を持つGoogleならではの動機ではないでしょうか。これはアプリ開発者にとっては好都合です。Flutterに直接の見返りを求めず、アプリ開発者ファーストで開発を進めていることが、ツールチェーンやライブラリの整合性確保、ドキュメントの整備等に良い影響を与えているようです。

## Widgetの捉え方
| Flutter | React Native | Xamarin |
|----|----|----|
|Widgetの再発明|OEM Widgetの抽象化|(OEM Widgetの抽象化)|
|||OEM Widgetの活用|

XamarinではOEM Widgetの有効活用を重視しているため、クロスプラットフォーム開発フレームワーク**ではない**と言われることがあります。
なお、Xamarin.FormsではOEM Widgetの抽象化も行っています。

React NativeはOEM WidgetをHTMLコンポーネント相当に抽象化していると言えばよいでしょうか。

FlutterにおけるWidgetの捉え方はかなり異なっています。先述のMaterial Designやアプリ固有ブランドUIを容易に構築するために、Widget開発の柔軟性を重視しています。そのために深いクラス継承を避け、目的別の小さなコンポジットの合成によってWidgetが成り立っています。また、Widgetの配置や構成が動的に変化するMaterial Designやアプリ固有ブランドUIを容易に実現することも重視しています。そのために、JSXのような宣言的だが静的なUIドメイン固有言語(DSL)を用いること無く、全てをDartで表現する道を選んでいます。加えて、Reactiveパターンを当初から念頭においたBuildパターン指向のWidgetにもなっています。なお、手続き型言語によるBuildパターンは宣言的でもあります。Dart 2.0では、より宣言的に見せるために、new/constキーワードをオプショナルにしました。
これらを捉えて上記の表ではWidgetの再発明と表現しています。

## 対象アプリアーキテクチャ
| Flutter | React Native | Xamarin |
|----|----|----|
|Reactive|Reactive|MVVM|

React Nativeは当然ながらReactで一斉を風靡したReactiveパターンを採用しています。
Reactiveパターンの発明と、それをモバイルに持ち込んだのはFacebookの功績でしょう。

FlutterもReactをリスペクトしてReactiveパターンを採用しています。
ただし、Webフロントエンドの開発手法を導入するのではなく、ネイティブモバイルアプリ開発フレームワークとして一から構築しています。

## (移行)ターゲット開発者 (プラットフォーム)

| Flutter | React Native | Xamarin |
|----|----|----|
|Webフロントエンド|Webフロントエンド| |
|Webバックエンド||Webバックエンド|
|既存モバイル他|||

C#の最大の利用シーンはWebバックエンドでしょうか。Xamarinでは、ともかくC#が好きな人がモバイルアプリもC#で開発できるようにした、というように感じます。

React Nativeはその名の通り、ReactでWebフロントエンドを開発していた人が、そのままモバイルアプリも開発できるようにした、ということでしょう。

Flutterはより野心的で、既存のモバイルアプリ開発者、Webフロントエンド開発者を中心に、Webバックエンドを含んだ開発リソースを広くモバイルアプリ開発に動員しようという気概を感じます。ちなみに、Flutterプロジェクト開始された時点で、DartはWebフロントエンドとWebバックエンドを主なターゲットとしていました。

## (移行)ターゲット開発者 (プログラミング言語)

| Flutter | React Native | Xamarin |
|----|----|----|
|Javascript|Javascript||
|||C#|
|Java|||
|Objective-C|||
|(Kotlin)||
|(Swift)||

繰り返しになりますが、XamarinにおけるC#採用の動機は、C#利用者をモバイルアプリ開発に動員することでしょう。
C#愛を感じます。

React NativeによるJavascript採用の動機も、Javascrip利用者をモバイルアプリ開発に動員することでしょう。
Javascriptの影響力を感じます。
もっとも、Javascriptの採用は副次的で、より重要なのは先述のWebフロントエンド開発者を動員することだと思いますが。

FlutterにおけるDart採用の動機は、オブジェクト指向言語の利用者を広くモバイルアプリ開発に動員することでしょう。
特に、Webフロントエンド開発におけるJavascript利用者、React Native、Cordova、Ionic等によるモバイル開発におけるJavascript利用者、モバイルアプリ開発者でまだJava、Objective-Cを利用している者にとって、よりモダンなDartが魅力になると考えているようです。Dartでは奇抜な構文を避け、あえて平凡な言語にしているのも、これら言語の利用者にとっての移行ハードルを下げるためです。
ちなみに、現在FlutterのPMを行っているHixieさんは以前はHTML5の仕様取りまとめを行っていた人です。そのためか、Web開発者のFlutterへの移行容易性にはDart言語レベルで非常に気を使っているようです。
当然ながら、KotlinやSwiftの利用者にも訴求したいところですが、現状のDartの実力はそこまではないでしょう。ともかく、移行のハードルが高くなければそれで良い、という感じです。とかくDartはKotlinやSwiftとの比較において、その言語機能要素について批判されがちですが、Flutterチームはそこまで言語機能要素を気にしている様子はありません。むしろ非機能(JIT+AOTコンパイル、高速なオブジェクトメモリアロケーション&GC)を重視してDartを採用したそうです。なお、DartチームはData Classや非NULL型の導入に邁進しています。

# さいごに

既に筆者がFlutter押しであることを感じていると思いますが、それは主に宗教(Google教)的理由からです。
ともあれ、機能要素の星取表の比較ではないコンセプトベースの比較をすると違った景色が見えてくると思いますので、試してみてください。