Flutterとはなにか

この記事はFlutter 全部俺 Advent Calendar 1日目の記事です。

このアドベントカレンダーについて

このアドベントカレンダーは @itome が全て書いています。

基本的にFlutterの公式ドキュメントとソースコードを参照しながら書いていきます。誤植や編集依頼はTwitterにお願いします。

記事一覧

Flutterとは何か

Flutterは一つのソースコードから複数のプラットフォームのアプリを作ることができるクロスプラットフォームのフレームワークです。 Android/iOSアプリについては既にProduction Readyで、Web対応も進んでいます。Desktopで動くFlutterも開発中らしいので今後Flutterだけでできることがより増えてきそうです。 開発言語はAltJSのDartという言語です。Dartに関しては3日目、4日目の記事で詳しく解説します。

また、Googleが開発している新しいOSであるFuchsiaはアプリ開発にFlutterを採用しており、すでにFuchsiaが動いているGoogle Nest HubではFlutterでアプリが作られています。

このアドベントカレンダーではFlutterの中でも特にAndroid/iOSアプリについて書いていきます。

Flutterの特徴

ハイパフォーマンスな描画

FlutterはネイティブのViewを使わずに独自のレンダリングエンジンでGPUを使って画面を描画しています。そのためネイティブ並みかそれ以上のパフォーマンスを出すことができます。

HotReloadによる高速な開発

Flutterは画面の状態を保存したまま、コードの変更を適用できるHotReloadという機能を持っているため、コード修正→実機で動作確認というイテレーションを高速に回すことができます。

マテリアルデザインのコンポーネントが豊富

FlutterはGoogleが開発していることもあって、マテリアルデザインを基本としてWidgetが作られています。一方でiOSらしいデザインのサポートはまだ十分とは言えないので、多くの場合iOSアプリもマテリアルデザインで作られることが多いです。

Googleが開発を主導しており、サポートが安定している

FlutterはGoogleが主導してOSSとして開発が進められており、新機能開発やバグ修正も盛んに行われています。執筆時のStableである1.9.1には、前のリリースから2ヶ月にもかかわらず1500以上のPull Requestがマージされています。

Flutterの仕組み

FlutterのGitHubリポジトリはフレームワークのAPIを提供しているflutter/flutter と低レイヤーの描画やネイティブAPIとのバインディングを実装しているflutter/engineに分かれていますが、 アプリを開発しているときに意識するのは基本的にフレームワーク部分だけです。

Flutter System Overview

Dartで書かれたアプリケーションコードは、フレームワークによる最適化を行われたのち、engineのコードを呼び出します。 engineはSkiaという2Dレンダリングのライブラリを使ってディスプレイに画面を描画しています。

このとき、実際に描画される画面はAndroidではSurfaceView、iOSではUIViewです。 つまりAndroidやiOSから見ると、画面と同じサイズのViewが一枚だけ置かれていて、Flutterアプリは全てその上だけで動いていることになります。

Dartはどこで動いているのか

Dartは現在ではAltJS言語として使われることが多いですが、Javascriptへのトランスパイラ以外にオリジナルのDartVMも持っており、Flutterではこちらが使われています。

DartVMはAndroid/iOSから与えられたスレッドプールの上で動いており、 dart:ui パッケージを通してengineに、 Platform Channel を通して各プラットフォームの機能にアクセスできます。 Dartのマルチスレッド機能である isolate はDartに割り当てられたスレッドプールを使って実現されています。 engineは自身のスレッドを管理しないので、スレッドの管理は各プラットフォームに任せられています。 これはスレッド管理をそれぞれのプラットフォームに最適な設定にできることを意図されていて、実際にAndroid/iOSとFuchsiaとWebとでは、Flutterのタスクランナーの割り当てられ方が異なります。

AOTコンパイルとJITコンパイル

Dart言語はAOT(Ahead Of Time)コンパイルに対応しています。これは事前にスクリプトをコンパイルしておいて機械語にしておくことで実行時にかかるスクリプトのパースなどのコストを減らす最適化方法です。 FlutterでもAOTコンパイルがされていますが、AOTコンパイルするとFlutterのHotReloadができなくなるため、リリースビルドでのみAOTコンパイルが行われ、デバッグビルドではJIT(Just In Time)コンパイルされるようになっています。

コンパイル方式の違いによって挙動が変わることはないので普段意識することはありませんが、パフォーマンスに差が出るためデバッグビルド時にはカクついていたアニメーションがリリースビルドでは滑らかに動くようなことはよくあります。 リリース前には必ずリリースビルドしたアプリを触ってみることをおすすめします。

参考

2日目の記事 :

https://itome.team/blog/2019/12/flutter-advent-calendar-day2