Xamarin と React Native と Flutter の違いを正しく理解しよう

DroidKaigi2018 でもセッションがあった Flutter がβ版になりました。

これでまた、にわかにクロスプラットフォーム開発ツール(以下 "X-Plat Tool" と略)が盛り上がってる気がします。 Flutter が出たからと言って、Xamarin や React Native など、先行する様々な X-Plat Tools が死ぬわけでもなく、ただ選択肢が増えて嬉しいやら戸惑うやら、ということです。

ここでは、Flutter と、先行する React Native、Xamarin を(独断を交えて)比較して、それらの違いを見てみたいと思います。

共通化できる(とされる)プラットフォーム

X-Plat Tool がどのプラットフォームまでカバーするかを比べてみます。ツールそのものに加え、フレームワークや言語自体も含めた広範な考えです。

Platform Xamarin/.NET ReactNative/JavaScript Flutter/Dart
iOS :thumbsup: :thumbsup: :thumbsup:
Android :thumbsup: :thumbsup: :thumbsup:
デスクトップ(Windows) :thumbsup:
デスクトップ(Mac) :thumbsup:
Web(フロントエンド) :thumbsup: :thumbsup:
Web(バックエンド) :thumbsup: :thumbsup: :thumbsup:

概ね、デスクトップアプリに対応するか、Webアプリに対応するかで選択肢が大きく変わります。

開発者に提供される API

X-Plat Tool が開発者にどんな「API セット」を提供するかを比べてみましょう。 ここでは2つに分類してみます。

A. 開発者は、X-Plat Tool の 独自API を利用する

この方式の X-Plat Tool は、それ専用のAPIセットを開発者に提供します。 例えば Flutter では Stack というレイアウトクラスを提供しますが、これは Android の FrameLayout に近いものと考えられます。 あるいは JSX や XAML などの DSL(Domain Specific Language) を使用する場合もあります。React Native では画面のデザインは JSX(return で HTML っぽいタグを返すアレ) を使用します。

  • :no_good: 新たに API を学習する必要がある(=プラットフォーム固有のAPI知識が活かせない)
  • :no_good: プラットフォーム固有の機能を使用するには Kotlin や Swift などネイティブの開発言語をツールを使わなければならない(= APIの相互運用性が低い )
  • :ok_woman: 複数のプラットフォームでコードを共通化できる(イマサラナニヲイッテルンダ)
  • :no_good: "共通API" と言いながら iOS でしか(Android でしか)動作しないかも知れない5

B. 開発者は、プラットフォーム固有の (薄いラッパー)API を利用する

こちらの方式は、プラットフォーム固有の API を、X-Plat Tool の言語でラップして提供します。Xamarin(Xamarin.Android)では、Android SDK の API が、ほとんどそのまま C# から呼び出せます。例えば Android SDK の android.location.LocationManager は、 Xamarin では Android.Locations.LocationManager として利用できます。

  • :no_good: それ自体はコードの共通化にならない(言語の標準APIやフレームワークでしか共通化できない)
  • :ok_woman: プラットフォーム固有のAPIが X-Plat Tool の言語からダイレクトに呼び出せる(= APIの相互運用性が高い )
  • :ok_woman: (上記であることから)開発やデバッグが一つの環境でシームレスに行える

できあがったアプリケーションのユーザーインターフェース

アプリのUIは、エンドユーザーの反応に最も影響するため、特に注意が必要です。 こちらも2つに分類しています。

あ. ネイティブのUIパーツを利用する

この方式では、X-Plat Tool での UI定義は プラットフォーム固有の UIパーツ にマップされます。例えば React Native での <Text> タグは、Android では TextView 、iOS では UITextField が使用されます。

  • :no_good: 複数のプラットフォームのUIパーツ群で、共通で存在する機能しか提供できない
  • :ok_woman: エンドユーザーにネイティブの「忠実な」UIを提供できる
  • :ok_woman: プラットフォーム固有OSSライブラリが比較的利用しやすい(基本的にはブリッジしてあげれば良い = UIパーツの相互運用性が高い)

い. X-Plat Tool が自力でUIパーツを描画する

こちらの方式は、ネイティブのUIパーツは使わず、X-Plat Tool が持つレンダリングエンジンを使用して自力でUIパーツを描画し、マウスやキーボードのイベントも自力でハンドリングして操作感を提供します。 (インターネット老人会の皆さまには「Adobe の Flash アプリだよ」とでも言えば伝わるかと思います。)

  • :no_good: ネイティブのUIパーツと見た目や操作感が微妙に異なる(かも知れない)
  • :no_good: ネイティブのUIに比べて動作がもっさりする(かも知れない)7
  • :no_good: プラットフォーム固有OSSライブラリが比較的利用しにくい(独自レンダリングエンジンの影響を考慮する必要がある = UIパーツの相互運用性が低い)14
  • :ok_woman: 「スタイル」を切り替えるだけで画面の Look and Feel を変更できる
  • :ok_woman: 複数のプラットフォームに「完全に同一のUI」を提供できる10

比較表

結局、言語もIDEも含めてモバイルネイティブアプリを主対象とした X-Plat Tools の比較表を作ってしまった。。。

  • Xamarin
  • React Native
  • Flutter
  • Titanium Mobile
  • RubyMotion
  • Qt
  • Delphi
  • Adobe AIR
  • NativeScript
  • RoboVM
  • Kotlin X-Plat(予想)

※ゲームエンジンやWebViewを使用するタイプの X-Plat Tools は、今回の比較軸とは変わってくると思うので載せていません(が、実際にはもちろんこれらも選択肢に加えるべきです)。

Xamarin ReactNative Flutter Titanium Mobile RubyMotion Qt Delphi Adobe Air Native Script RoboVM Kotlin X-Plat(予想)
(主な)提供者 Microsoft Facebook Google Appcelerator9 Scratchwork Qt Company Embarcadero Technologies8 Adobe Progress Software Xamarinが買収後死亡4 JetBrains
開発言語 C# JavaScript Dart JavaScript Ruby C++ Object Pascal Action Script JavaScript Java Kotlin
(主な)開発環境 Visual Studio As you like IntelliJ/VSCode12 Titanium Studio As you like As you like RAD Studio Flash Builder As you like Eclipse CLion13
対応Platform(言語含む) iOS, Android, Win, Mac, Web(Back) iOS, Android, Web(Front), Web(Back) iOS, Android, Web(Front), Web(Back) iOS, Android, Web(Front), Web(Back) iOS, Android, Web(Back) iOS, Android, Win, Mac, Web(Back) iOS, Android, Win, Mac iOS, Android, Win, Mac iOS, Android, Web(Front), Web(Back) iOS, Android, Win, Mac, Web(Back) iOS, Android, Win, Mac, Web(Front), Web(Back)
提供される API B.薄いラッパーAPI + A.独自API6 A.独自API A.独自API A.独自API B.薄いラッパーAPI A.独自API A.独自API + B.薄いラッパーAPI1 A.独自API A.独自API + B.薄いラッパーAPI3 B.薄いラッパーAPI B.薄いラッパーAPI
UIの提供方式 あ.ネイティブ あ.ネイティブ い.独自 あ.ネイティブ あ.ネイティブ あ.ネイティブ?2 い.独自+あ.ネイティブ11 い.独自 あ.ネイティブ あ.ネイティブ あ.ネイティブ

月並みなまとめですが、クロスプラットフォーム開発ツールを選択するには、

  • ターゲットにするプラットフォーム
  • 提供者の規模、サポート、継続性
  • 開発言語や開発ツール vs チームメンバのスキルセット(あるいは習得容易性)

を評価し、さらに開発するアプリの性質に応じて、

  • X-Plat Tool の標準機能で行えない機能がどのくらいあるか?
  • X-Plat Tool の標準機能で行えない機能をどのように補完するか?(共通側で実装するか、ネイティブ側で実装するか、etc)

を検討することになると思います。 (もちろん X-Plat Tool を「採用しない」という選択肢も含めて。 あるいは Cordova のようなWebViewベースのX-Plat開発ツールもあれば、Unityのようなゲームエンジン系のX-Plat開発ツールも場合によっては候補になり得ます。)

例えば Flutter は美麗なアプリを迅速に開発できる、と謳われていますが、個人的には Webアプリプラットフォームの kintone をイメージさせます(筆者は kintone について、Flutter と同じく『美麗なWebアプリを迅速に開発できるツール』と(主観で)認識しています。対して Xamarin や React Native は Salesforce や SharePoint のように「なんでもできるが作るのはやや大変である」と相対的に思います)。 また Flutter について、「標準UIだけでなく凝ったUIも容易に実現できる」とのご意見をいただきました。 さらに、 React Native も、「Webの技術(CSSやAnimated API)でカスタムUIを用意に実現できる」とのツイートがあります。 この記事は推測も多く含んでいるので、事実は、経験者・識者の方の情報を信じるのが一番です。

Kotlin Multi platform にはとても期待しています。うまく進化して流行ってくれれば、(現状での)モダンな言語で、プラットフォーム全方位な開発が実現できるんじゃないかなあ、と。

単純な比較表には現れない得意・不得意点もあるはずなので、日頃からアンテナ高く、できればたくさんつまみ食いしておきたいですね。

参考


  1. Titanium Mobile はこれが多かったという印象が深く心に刻まれています。。。
  2. Flutter や DelphiXE(の FireMonkey) では GPU を利用した高速なレンダリングが可能になっているとのことです。
  3. https://twitter.com/najeira/status/969106318098223104 によると、現行の Flutter では実質行えない模様です。
  4. https://twitter.com/najeira/status/968774727022948352 を見て、同じ理由で昔 Flash AIR を使ったのを思い出しました。
  5. コメント より。指定によりネイティブに描画させることもできるとのことです。
  6. エイリアンウィジェット と呼ばれるネイティブに依存しないViewも存在する模様。
  7. NativeScript Documentation Chapter 6—Accessing Native APIs 参照。
  8. Delphiならここまでできる︕ iOS / Androidネイティブアプリ構築術 参照。
  9. Xamarin.Android, Xamarin.iOS などは 「B」、Xamarin.Forms というフレームワークは 「A」 に該当します。
  10. Kotlin/Native - Kotlin Programming Language
  11. Get Started: Configure Editor - Flutter では IntelliJ と VS Code が紹介されています。
  12. https://github.com/robovm にリポジトリはある模様。
  13. Embarcadero Technologies は IDERA に買収され、現在は小会社となっています。
  14. Appcelerator は Axway に買収され、現在は小会社となっています。