モバイルアプリ開発は、Flutter一択なのか？-2021版-

こんにちは！ Tetsukick(菊池哲平)です。
2021年1月現在、インドネシア([PT.AQ Business Consulting Indonesia](https://aqi.co.id/))でモバイルアプリ開発の技術顧問をしております。
iOS歴5年、Flutter歴1年半。[個人でもアプリ開発してます。](https://apps.apple.com/ca/developer/teppei-kikuchi/id1504163412)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261934/268c909b-c9ca-36b7-157d-3b835a2a109f.png)


本記事は、[2020年11月にZennに投稿した記事](https://zenn.dev/tetsukick/articles/c297b6ee1e64397432e5)の改訂版になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261934/11e01f11-c691-e9ee-7ee9-18eda542b317.png)

Zennで本を出版しております[flutter chips](https://zenn.dev/tetsukick/books/06ee607e30e243)(30,000字程度)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261934/5183aafc-d1d7-534f-f618-031f10790fdc.png)

## 本記事の対象読者
- モバイルアプリ開発者
- Flutterの今後の可能性を知りたい方
- モバイルアプリ開発案件を検討中で技術選定をされている方
- 本記事のタイトルが気になる方

## 序
今回インドネシアでモバイル開発の技術顧問をさせていただく中で、Flutterの提案から導入までを実施し、実際に導入に至ることができましたので、その過程で用いた技術的根拠等々をシェアいたします。
実際に非技術者に対しても提案をしましたので、そのままお使いいただくことも可能かと思います。
PPT素材が必要な方いましたら[Twitter_@tpi29](https://twitter.com/tpi29)までDMいただければと思います。
日本語文献や英語文献も参考にしておりますので、少しでもお役に立てばと思います。

## 最近の更新
2021年版のDeveloperの[ロードマップ](https://roadmap.sh/frontend)が公開されました。

結果からお伝えすると、、
モバイル開発におけるフレームワークは、React Nativeが取り上げられております。

とはいえ僕の記事を読んでもらえば少し分かるかもしれませんが、現状そこまで大差はないと思っております。結局は好きな言語を身につけるのが一番かと。。笑
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261934/5e72897b-15db-36e2-0879-da14a77c897a.png)


## ネイティブ開発とクロスプラットフォーム開発
まず、モバイルアプリ開発をするにあたって、大きく２つに分類(ネイティブ開発とクロスプラットフォーム開発)できます。

### ネイティブ開発とは
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261934/62a87614-bf97-1ede-8121-02253db2e9af.png)

iOSアプリ、Androidアプリに対してそれぞれ独自の言語を用いて開発する開発手法です。
iOSであれば、Objective-CやSwift。
Androidであれば、AndroidJavaやKotlin。
での開発を指します。

モバイルアプリ開発における最も基本的な開発手法になります。

### クロスプラットフォーム開発
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261934/82cb1115-01af-9c7a-e071-4707f63a6e55.png)
クロスプラットフォーム開発とは、AndroidやiOS等の複数のプラットフォームにまたがって開発を行うことのできる手法になります。
具体的には、XamarinやCordova、ReactNative、Flutter、Outsystems等々、最近では、プログラミングを必要としないノーコード開発ツールもいくつか見受けられるようになりました。

## ネイティブ開発 VS クロスプラットフォーム開発
では、まずネイティブ開発とクロスプラットフォーム開発の比較をいたします。
以下の項目で比較いたしますが、各項目の重要度は読者様で配分頂いた上で実際に選定していただければ良いかと思います。
- 開発効率
- 保守・運用
- パフォーマンス
- 端末固有機能
- 最新機能対応
- 最新OS対応

### まとめ
結論はこちら。以下、各項目に関して詳細に記載いたします。
![ネイティブ開発 VS クロスプラットフォーム開発(まとめ)](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261934/f7c474e2-049c-37dd-b00f-bcc80ad0903d.png)

### 開発効率
開発効率においてはクロスプラットフォーム開発に軍配があがります。
![ネイティブ開発 VS クロスプラットフォーム開発(開発効率)](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261934/c662f67b-6e01-4030-b67c-c5ad812ef33f.png)


#### 人的リソース
##### ネイテイブ開発
ネイティブ開発は各OSごとの異なる言語(iOS: Swift, Android: java, Kotlin)のエンジニアが必要(通常最低2名)

##### クロスプラットフォーム開発
一つの言語で開発可能。

#### 開発環境
クロスプラットフォーム開発の多くのプラットフォームでホットリロード機能（コンパイル不要でソースコードの修正をアプリに反映させる機能）を有している。
通常ネイティブ開発では、コンパイルごとに10秒-1分程度の時間がかかるので、その時間を削減することができる。

#### その他
ネイティブの場合、ソースコードは各OSごとに必要で基本的にロジックをあわせる必要があるが、開発者間での調整コストやソースコード間でずれが生じるリスクが発生する。
これに関してはProtocol Buffers等で極力ロジックを統一する等の対策も可能だが、すべてを補完できるわけではない。

### 保守・運用
保守・運用面では、クロスプラットフォーム開発に軍配があがります。
![ネイティブ開発 VS クロスプラットフォーム開発(保守運用)](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261934/a1ae2f1c-0f17-fed8-f6fb-aa4f941eb612.png)


#### 人的リソース
##### ネイテイブ開発
ネイティブ開発は各OSごとの異なる言語(iOS: Swift, Android: java, Kotlin)のエンジニアが必要(通常最低2名)

##### クロスプラットフォーム開発
一つの言語で開発可能。

#### 不具合・改修リスク
ネイティブ開発では各OSごとにソースコードが存在するため、不具合の発生リスクも増加する。
改修の際は両OSでの対応が必要になる。

### パフォーマンス
パフォーマンス面においては、ネイティブ開発に軍配があがる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261934/555f59de-3885-cd5a-efa0-6d88bbf91614.png)


#### レンダリング(画面描画)パフォーマンス
各プラットフォームにより異なるが、クロスプラットフォームはネイティブUIを呼び出す処理を行うもの、WebViewへのレンダリングを行うもの、独自レンダリングエンジンを使用するもの、等ありますが、基本的にはネイティブのレンダリングパフォーマンスに比較すると劣ります。

以下はパフォーマンスの比較例です。
リストを表示する上でのパフォーマンスを比較しています。
![リスト表示サンプル](https://miro.medium.com/max/446/1*AvzN9TEZbNo2jjM-OP0GMg.gif)
![Android比較表](https://miro.medium.com/max/700/1*tCqV2lrsWL-NVY8G9BLo5Q.jpeg)![iOS比較表](https://miro.medium.com/max/700/1*ExXQl4dOmUENkXsmwEVitw.jpeg)

[こちらのサイトから参照](https://medium.com/swlh/flutter-vs-react-native-vs-native-deep-performance-comparison-990b90c11433)

### 端末固有機能
端末固有機能についてはネイティブ開発に軍配があがる。
![ネイティブ開発 VS クロスプラットフォーム開発(端末固有機能)](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261934/840e4603-3dc8-8de2-22d2-50b11a5ab7c6.png)

#### 一般的端末固有機能
カメラ機能、プッシュ通知、GPS、生体認証等の機能はプラグインによりサポートされているため、
クロスプラットフォーム開発においても、懸念することはほとんどない。

#### 特殊な端末固有機能
ウィジェット機能、特殊端末との接続（クレジット端末など）、フィットネスAPI等の連携、センサー関連の使用（加速度センサー等）に関しては、プラットフォームにより異なるが、プラグインが提供されていなかったり、プラグインが不十分な場合があり、自作等での対応が必要になるケースがある

### 最新機能・最新OS対応
最新機能・最新OS対応においては、ネイティブ開発に軍配があがる。
![ネイティブ開発 VS クロスプラットフォーム開発(最新機能)](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261934/27fd094b-164a-7282-0f8e-1d56c2d64ab8.png)


#### ネイテイブ開発
最新OSのbeta版や開発用のIDEのbeta版が提供され、リリース前から検証や開発を実施し、備えることが可能。

#### クロスプラットフォーム開発
リリース後にオープンソース上の開発者間で対応バージョンが追ってリリースされることになり、対応を待つ必要がある。
iOSでもAndroidでも、最新OSのリリースの約一年後には、最新OSに対応していないアプリは新たに申請できなくなる風潮がある。

### 結論(ネイティブ開発 VS クロスプラットフォーム開発)
アプリの要望や開発予算、人的リソース等の状況により、ネイティブ開発、クロスプラットフォーム開発の選定の大きな要因となる。

#### アプリの要望
特殊なネイティブ機能や最新機能を使用するアプリでは、ネイティブ開発が好ましい。
一般的な機能にとどまるアプリに関しては、クロスプラットフォーム開発が好ましい。

#### 開発予算、人的リソース
開発予算、人的リソースが豊富な場合は、ネイティブ開発が好ましい。
予算や人的リソースに懸念がある場合は、クロスプラットフォーム開発が好ましい。

## クロスプラットフォーム開発
### まとめ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261934/f01bf28e-e85a-59fe-63ff-b04bbe60e1ac.png)


### クロスプラットフォーム開発分類

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261934/48d376af-a1e4-bcef-d7c7-5b50c0229994.png)

上記のようにクロスプラットフォーム開発は主に3つの種類に分類されます

#### ネイテイブUI型
単一言語をネイティブのUIに変換して表示、パフォーマンスは比較的に高いが、変換にかかる時間だけパフォーマンスが若干落ちる。各ネイティブのUIを使用できるため、単一言語で各OSに合わせたUIを作成可能

#### オリジナルUI型
プラットフォーム固有のレンダリングエンジンを用いているため、ゲームアプリなど自由度の高いグラフィック表現が可能。パフォーマンスは各プラットフォーム次第だが、こちらも比較的高い。Unityもこちらに分類される。

#### WebUI型
WebView上に描画を行うため、パフォーマンスが低い。Webと同じリソースを活用できるため、Webサイトのアプリ化等に優れている。ネイティブの機能との連携もやや困難

### ReactNative VS Flutter
本記事では、私自身の経験があり、クロスプラットフォーム開発でもよく比較されるReactNativeとFlutterの比較を行います。

#### まとめ
以下の項目で比較をいたします。
- 言語
- 生産性
- UI自由度
- 開発頻度
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261934/8f138196-80b5-486c-b18b-3cc05acff633.png)

#### 言語
言語に関して、ReactNativeで採用されているJavascriptの方が開発者数や情報量などで大いに優勢。

下記のサイトでは、かなりの大差ですね。

| ランキング | 言語 | Share率 |
|:-:|:-:|:-:|
| 3位 | Javascript | 8.44% |
| 21位 | Dart | 0.56% |

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261934/7271e0bf-c4b2-c274-5b70-d4e8b98917e9.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261934/73c71ad1-7431-a6cb-e832-07a53a828bbb.png)


[こちらのサイト参照](https://pypl.github.io/PYPL.html)

#### 生産性
生産性に関しては、ホットリロード機能はどちらもサポートされているが、インタフェースの作成において、XDから正式に変換プラグインのサポートやアニメーションフォーマットのサポート([RIVE](https://qiita.com/tetsukick/items/c2ac167e2e7849ff6ff0))などインタフェースの開発効率が高い

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261934/758e8d05-0006-5039-e5a0-ab65b042bd18.png)


#### UI自由度
UI自由度に関しては、ネイティブコンポーネントだけでなく、独自のUIコンポーネントライブラリを保有するFlutterの方が優れている。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261934/50205f8e-4f85-26f1-f46b-07a69f050129.png)


#### 開発頻度
OSSとして、言語の改良速度がFlutterが非常に活発な状態にあります。
質問投稿サイト(StackOverFlow)の質問数やGoogle検索の数に関してもFlutterが優れている。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261934/8715ac98-f4f8-8369-5fb9-8e759daba98b.png)
[github_flutter](https://github.com/flutter/flutter/pulse)
[github_reactnative](https://github.com/facebook/react-native/pulse)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261934/d05a170c-de93-33b4-b136-a7b7141c7047.png)
[Google Trends](https://trends.google.com/trends/explore?q=flutter,React%20Native,Ionic,Xamarin)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261934/bb263354-ecc5-9683-6c44-0cdc77515734.png)
[StackOverFlow](https://insights.stackoverflow.com/trends?tags=flutter%2Creact-native%2Ccordova%2Cxamarin)

### 結論（クロスプラットフォーム開発比較）
プラットフォームの選定には、開発者の習熟言語、アプリの要望にも起因する。

#### アプリの要望
既にWebサイト構築済みで、特異な機能のないアプリ開発であれば、Cordova等のWebリソースを使用できる開発が好ましい。
OSごとのネイティブUIの表現を重視する場合は、ReactNativeでの開発が好ましい。
ユーザの要望などUIの変更への対応、開発速度が求められる場合はFlutterでの開発が好ましい。

## 個人的所見
ここ最近の動向を見ても、ReactNativeは、Facebookのネイティブ化などの流れがあることに反して、Flutterは、各種GoogleのアプリがFlutterに変更されたり、中国系のAlibabaやBaidu,TencentなどがFlutterでの開発をしていたり([Flutter showcase](https://flutter.dev/showcase))、そういった面でも信頼ができるのではと思います。

また実際に、私がインドネシアで比較的容易に導入できた背景としては、約９割のスマホユーザがAndroidユーザである背景から、ユーザに広く普及しているUIがMaterial Designであるため、その開発においての優位性があるなども別途決め手の一つにはなっていたかと思います。

## 参考記事
- [Flutter vs React Native vs Native: Deep Performance Comparison](https://medium.com/swlh/flutter-vs-react-native-vs-native-deep-performance-comparison-990b90c11433)
- [Flutter vs React Native: A Developer’s Perspective](https://medium.com/flawless-app-stories/flutter-vs-react-native-a-developers-perspective-8914ca240a89)
- [The Great Framework Battle (Flutter vs. React Native)](https://www.crema.us/blog/the-great-framework-battle-flutter-vs-react-native)
- [What is Flutter? Why Flutter?](https://speakerdeck.com/tetsukick/what-is-flutter-why-flutter)
- [モバイルアプリ開発 クロスプラットフォーム開発 比較](https://note.com/tetsu_no_te/n/n9eaa8aefda01)
- [Flutter](https://flutter.dev/)