はじめに
この記事は、What’s Revolutionary about Flutterを翻訳したものです。
最近よく聞くFlutterについての理解を深めたく、人気記事を日本語化しました。
QiitaにてFlutter,Dartなどで検索しても中々記事が見当たらないので、QiitaにおけるFlutterの啓蒙活動の一環も兼ねていますし、自身の英語力向上も兼ねています。
なお、誤訳がありましたらリクエストを頂けると幸いです。
Flutterとはなにか?
FlutterSDKとは、かつて一般的であった「クッキーカッター」のようなアプリとは全く離れた、非常に美しいネイティブアプリを作成する新たな方法です。Flutterを試す人はきっとこういったアプリを気にいるでしょう。これやこれまた、これなどです。また、有志によって編集されたFlutterについての動画と記事リストもありますので参照ください。
他の新たなシステムと同様に、皆さんは「Flutterは他と何が違うのか」別の言い方をすると、「何が新しく、何がエキサイティングなのか?」と思っていることでしょう。それは正しい質問です。そしてこの記事では、何が新しいのか、だけでなく、何故という部分に踏み込んで、技術的な観点からお答えしています。
モバイルアプリ開発の簡単な歴史
モバイルアプリ開発は、比較的最近発展してきた分野です。サードパーティの開発者は10年にも満たないうちにモバイルアプリを開発することができたので、開発ツールがまだ進化していることは驚きではありません。
OEM SDK
Apple iOS SDKは2008年にリリースされ、Google Android SDKは2009年にリリースされました。これらふたつのSDKはObjective-CとJavaのそれぞれ異なる言語に基づいています。
あなたのアプリはプラットフォームにウィジェットを作成したり、カメラのようなサービスにアクセスしたりします。ウィジェットはスクリーンキャンバスにレンダリングされ、イベントはウィジェットに戻されます。上記はシンプルなアーキテクチャですが、プログラミング言語はもちろんのこと、ウィジェットが異なるため、プラットフォームごとに別々にアプリを作成する必要があります。
WebViews
最初のクロスプラットフォームのフレームワークはJavaScriptとWebViewに基づいていました。例えば、以下の関連したフレームワーク(PhoneGap、Apache Cordova、ionic...)が存在します。AppleがiOS SDKをリリースする以前は、サードパーティの開発者にiPhone向けのWebアプリを構築するように奨励したので、Web技術を使ってクロスプラットフォームのアプリを構築することは明らかなステップでした。
アプリではHTMLを作成し、それをプラットフォーム上のWebViewに表示します。JavaScriptのような言語ではネイティブコード(サービスなどの)と直接対話することは難しいので、JavaScriptレルムとネイティブレルムのコンテキスト切り替えを行う「ブリッジ」を経由することは難しいことに注意してください。プラットフォームサービスはそれほど頻繁に呼び出されないため、パフォーマンスの問題はあまり発生しませんでした。
Reactive Views
ReactJS(およびその他)のようなリアクティブWebフレームワークは、主にリアクティブプログラミングから借用されたプログラミングパターンを使用して、Webビューの作成を簡単にしているために人気が高まっています。
React Native は広く普及しています(また、その価値もあります)が、JavaScriptレルムはネイティブ領域のOEMにアクセスするため、それらのブリッジを通過する必要があります。ウィジェットは、通常、アニメーション、トランジション、またはユーザが指で画面上の何かを「スワイプ」しているときに、非常に頻繁に(1秒間に60回)アクセスされるため、パフォーマンス上の問題が発生する可能性があります。 React Nativeについての記事(Reactネイティブアプリの限界と乗り越え方)の中には以下のように言及されています。
パフォーマンスのボトルネックは、あるレルムから別のレルムに移動するときによく発生します。パフォーマンスの良いReactネイティブアプリを設計するには、ブリッジを最小限に抑える必要があります。
Flutter
React Nativeと同様に、Flutterはリアクションスタイルのビューも提供します。 Flutterは、コンパイルされたプログラミング言語、つまりDartを使用してJavaScriptブリッジの必要性によって引き起こされるパフォーマンスの問題を回避するために、別のアプローチを採用しています。 Dartは、複数のプラットフォーム用のネイティブコードに "事前に"(AOT)コンパイルされています。これにより、Flutterはコンテキストスイッチを行うJavaScriptブリッジを経由せずにプラットフォームと通信できます。ネイティブコードにコンパイルすると、アプリの起動時間も短縮されます。
FlutterがJavaScriptブリッジを必要とせずにリアクティブビューを提供する唯一のモバイルSDKであるという事実は、Flutterを素晴らしいと評価するには十分なはずですが、Flutterについてははるかに画期的なことがあり、それはウィジェットを実装する方法です。
Widgets
ウィジェットは、ビューとアプリケーションのインターフェースに影響を与え、コントロールする要素です。ウィジェットはモバイルアプリの最も重要な部分の1つであると言っても過言ではありません。実際、ウィジェットだけでアプリを作ることができます。
- ウィジェットにおいて見栄えと自然さは重要な要素です。ウィジェットは見栄えがよくなければなりません。また、自然に感じられる必要があります。
- ウィジェットは早く動作しなければなりません。ウィジェットツリーの作成、拡大、画面にレイアウト、レンダリング、アニメーション化などを行う必要があります。
- 現代的なアプリケーションの場合、ウィジェットは拡張可能でカスタマイズ可能でなければなりません。開発者は、楽しい新しいウィジェットを追加し、すべてのウィジェットをカスタマイズしてアプリのブランドに合わせたいと考えています。
Flutterには、見た目と使用感が良く、速く、カスタマイズ可能で拡張可能なウィジェットを含む新しいアーキテクチャがあります。FlutterはOEMウィジェット(またはDOM WebViews)を使用せず、独自のウィジェットを提供することに強みがあります。
Flutterは、ウィジェットとレンダラーをプラットフォームからアプリ内に持ち腰、カスタマイズして拡張できるようにします。プラットフォームのFlutterに必要なのは、デバイス画面に表示され、イベント(タッチ、タイマーなど)やサービス(場所、カメラなど)にアクセスできるようにウィジェットをレンダリングするキャンバスです。
Dartプログラム(緑色)とデータのエンコードとデコードを行うネイティブプラットフォームコード(iOSまたはAndroid用の青色)の間にはまだインターフェイスがありますが、これはJavaScriptブリッジよりも桁違いに速いです。
ウィジェットとレンダラーをアプリに移動すると、アプリのサイズに影響します。 AndroidのFlutterアプリの最小サイズは約6.7MBで、これは同等のツールで構築された最小限のアプリに似ています。 Flutterのメリットがトレードオフ的価値があるかどうかはあなた自身が決定しますが、この記事ではこれらのメリットを説明します。
Layout
Flutterの最大の改善点の1つはレイアウトの仕方です。レイアウトは、一連のルール(制約とも呼ばれます)に基づいてウィジェットのサイズと位置を決定します。
伝統的に、レイアウトは、任意のウィジェットに適用することができる大きな一連のルールを使用します。ルールは複数のレイアウトメソッドを実装します。 CSSはよく知られているのでCSSを元に説明します(AndroidとiOSのレイアウトは基本的に似ていますが)。 CSSには、HTML要素(ウィジェット)に適用されるプロパティ(ルール)があります。 CSS3は375のプロパティを定義しています。
CSSには、(複数の)ボックスモデル、浮動要素、表、テキストの複数の列、ページングされたメディアなど、多数のレイアウトモデルが含まれています。フレックスボックスやグリッドのような追加のレイアウトモデルは後で追加されました。開発者とデザイナーはレイアウトをよりコントロールする必要があり、必要なものを得るためにテーブルと透過イメージを使用していたからです。従来のレイアウトでは、新しいレイアウトモデルを開発者が追加できないため、フレックスボックスとグリッドをCSSに追加してすべてのブラウザに実装する必要がありました。
伝統的なレイアウトのもう一つの問題は、ルールがお互いにやりとりできる(そして衝突する)ことであり、エレメントには数十のルールが適用されることがあります。これはレイアウトを遅くします。さらに悪いことに、レイアウトの性能は一般にN次のN乗(N-ordered)であるため、要素の数が増えるとレイアウトがさらに遅くなります。
Flutterは、GoogleのChromeブラウザチームのメンバーによる実験として開始されました。伝統的なレイアウトモデルを無視すれば、より高速なレンダリングを実現できるかどうかを見たいと思っていました。数週間後、我々は大幅なパフォーマンス向上を達成しました。また、以下の発見がありました。
- ほとんどのレイアウトは比較的シンプル:スクロールページのテキスト、サイズと位置がディスプレイのサイズにのみ依存する固定長方形、テーブルやフローティング要素など。
- ほとんどのレイアウトはウィジェットのサブツリーにローカルであり、そのサブツリーは通常1つのレイアウトモデルを使用するため、これらのウィジェットでサポートされる必要があるルールは少数です。
レイアウトをどうするかを念頭に置けば大幅に簡略化できることがわかったのです。
- レイアウトルールの大きなセットを持つ代わりに、各ウィジェットは独自の単純なレイアウトモデルを指定します。
- 各ウィジェットは考慮すべきレイアウトルールのセットがずっと小さいので、レイアウトを大幅に最適化することができます。
- レイアウトをさらに単純化するために、ほとんどすべてをウィジェットに変えました。
レイアウト付きの単純なウィジェットツリーを作成するためのFlutterコードを示します。
new Center(
child: new Column(
children: [
new Text('Hello, World!')),
new Icon(Icons.star, color: Colors.green)
]
)
)
このコードはどのようなものを生み出すか想像するに簡単な意味を持ちますが、結果は以下となります。
このコードでは、すべてがレイアウトを含むウィジェットです。 Centerウィジェットは、その子をその親の中に配置します(たとえば、画面)。列レイアウトウィジェットは、子(ウィジェットのリスト)を垂直に配置します。この列にはTextウィジェットとIconウィジェット(プロパティ、その色があります)が含まれています。
Flutterでは、センタリングとパディングはウィジェットです。テーマはウィジェットで、子供たち(children)に適用されます。アプリケーションやナビゲーションも全てウィジェットです。
Flutterには、列だけでなく、行、グリッド、リストなどレイアウトを行うためのウィジェットが数多く含まれています。さらに、Flutterにはスクロールに使用される「スライバーレイアウトモデル」というユニークなレイアウトモデルがあります。 Flutterのレイアウトは非常に速く、スクロールに使用できます。それについて少し考えてみましょう。スクロールは、画面イメージが物理的スクリーンを横切ってドラッグされるときに、指が画面イメージに触れたように感じるほどに、滑らかでなければなりません。
スクロールにレイアウトを使用することで、Flutterは次のような高度なスクロールを実装できます。これらはアニメーションGIF画像であり、Flutterはさらにスムーズです。これらのアプリケーションを自分で実行することができます(そして、そうする必要があります)。この記事の最後にある「参考文献」セクションを参照してください。
ほとんどの場合、Flutterは1回のパスでレイアウトを行うことができます。これは線形時間を意味するため、多数のウィジェットを処理できます。 Flutterもキャッシングなどの作業を行い、可能な限りレイアウトを行わないようにしています。
Custom design
ウィジェットは今ではアプリケーションの一部になっているので、新しいウィジェットを追加したり、既存のウィジェットをカスタマイズして異なる見た目を付けたり、会社のブランドと適合させることができます。モバイルデザインのトレンドは、数年前に一般的だったクッキーカッターアプリや、ユーザーを喜ばしせるものとなり、賞を獲得しています。
Flutterには、Android、iOS、Material Design用の豊富でカスタマイズ可能なウィジェットセットが用意されています(実際、FlutterはMaterial Designの最高の忠実度で実装がなされています)。我々はFlutterのカスタマイズ性を利用して、これらのウィジェットセットを構築し、複数のプラットフォーム上のネイティブウィジェットの使用感に合わせました。アプリケーション開発者は、同じカスタマイズ機能を使用して、ウィジェットを自分の望ましい方向へと調整することができます。
More about Reactive Views
リアクティブWebビューのライブラリは仮想DOMを導入しました。 DOMはHTMLドキュメントオブジェクトモデルであり、HTMLドキュメントを操作するためにJavaScriptによって使用されるAPIであり、要素のツリーとして表されます。仮想DOMは、プログラミング言語のオブジェクト(この場合はJavaScript)を使用して作成されたDOMの抽象バージョンです。
(ReactJSなどのシステムによって実装された)反応的なWebビューでは、仮想DOMは変更されず、何か変更があるたびにゼロから再構築されます。仮想DOMは実際のDOMと比較され、一連の最小限の変更が生成され、実際のDOMを更新するために実行されます。最後に、プラットフォームは実際のDOMを再描画し、それをキャンバスに描写します。
これは非常に多くの余分な作業のように見えるかもしれませんが、HTML DOMを操作することはコストが高いので十分に価値があります。
React Nativeも同様のことをしますが、モバイルアプリ向けです。 DOMではなく、モバイルプラットフォーム上のネイティブウィジェットを操作します。仮想DOMの代わりに、ウィジェットの仮想ツリーを構築し、それをネイティブウィジェットと比較し、変更されたウィジェットのみを更新します。
React Nativeはブリッジを介してネイティブウィジェットと通信しなければならないことを覚えておいてください。ウィジェットの仮想ツリーはブリッジを最小限に抑え、ネイティブウィジェットを使用できるようにします。最後に、ネイティブウィジェットが更新されると、プラットフォームはそれをキャンバスにレンダリングします。
React Nativeはモバイル開発にとって大勝利を納め、Flutterにインスピレーションを与えましたが、Flutterはこれをさらに進歩させました!
Flutterでは、ウィジェットとレンダラーがプラットフォームからユーザーのアプリに持ちこされていることを思い出してください。ネイティブOEMウィジェットは操作することができませんので、仮想ウィジェットツリーはウィジェットツリーになりました。 Flutterはウィジェットツリーをレンダリングし、それをプラットフォームキャンバスにペイントします。これは素敵でシンプルです(そして速い)。さらに、アニメーションはユーザー側で発生するため、アプリでそれをより詳細に制御できます。
Flutterレンダラー自体は興味深いものです。スクリーン上で更新する必要のあるウィジェットのみをレンダリングするために、いくつかの内部ツリー構造を使用しています。たとえば、レンダラーは、structural repainting using compositing(画面上の矩形領域で行うより効率的なウィジェットによる「構造的」という意味)を使用します。変更されていないウィジェットは、移動したウィジェットであっても、キャッシュからbit blitされ、超高速です。これは、先進的なスクロールでも、Flutterでスムーズにスクロールできるようにするものの1つです。
Flutterレンダラーを詳しく見るには、このビデオをお勧めします。 Flutterはオープンソースなので、コードを見ることもできます。もちろん、レンダラー、コンポジッター、アニメーション、ジェスチャー認識、ウィジェットなどのスタック全体をカスタマイズしたり、置き換えたりすることもできます。
The Dart programming language
リアクティブビューを使用する他のシステムと同様に、Flutterは新しいフレームごとにビューツリーを更新するため、1つのフレーム(60分の1秒)だけ存続する多くのオブジェクトを作成します。幸い、Dartはオブジェクト(特に短命のもの)が比較的効率的であるため、これらの種類のシステムでは非常に効率的な「世代別ガベージコレクション」を使用します。さらに、オブジェクトの割り当ては、高速でロックを必要としない単一のポインタバンプで行うことができます。これは、UIジャンクとスタッターを避けるのに役立ちます。
また、Dartには「ツリーシェイキング」コンパイラがあります。このコンパイラには、アプリケーションに必要なコードだけが含まれています。 1つまたは2つだけ必要な場合でも、大きなウィジェットのライブラリを自由に使うことができます。
ダートの詳細については、「Why Flutter uses Dart」をお読みください。
Hot Reload
Flutterの最も一般的な機能の1つは、高速でステートフルなホットリロードです。 Flutterアプリが実行されているときに変更することができます。変更されたアプリのコードをリロードし、中断した場所から、1秒未満で続けることができます。アプリでエラーが発生した場合は、通常はエラーを修正してから、エラーが発生しなかったかのように処理を続けます。あなたが完全なリロードをしなければならないときでさえ、それは速いです。
これにより開発者はアプリを再起動することなくほぼ即座に結果を見ることができます。
Compatibility(互換性)
ウィジェット(およびレンダラー)はプラットフォームではなくアプリの一部であるため、「互換ライブラリ」は必要ありません。あなたのアプリは機能するだけでなく、最新のOSバージョン(Android Jelly Bean以降、iOS 8.0以降)でも同じように動作します。これにより、旧バージョンのOSでアプリケーションをテストする必要性が大幅に軽減されます。さらに、あなたのアプリケーションは将来のOSバージョンで動作する可能性があります。
我々は一つの潜在的な懸念についてよく質問されることがあります。 FlutterはOEMのネイティブウィジェットを使用しないため、新しい種類のウィジェットをサポートする新しいバージョンのiOSやAndroidが登場したり、既存のウィジェットの外観や動作が変更されたときにFlutterウィジェットが更新されるのに時間がかかるのではないか?ということです。それについての回答は以下です。
- まず、GoogleはFlutterの大規模な内部ユーザーです。そのため、現在のOEMウィジェットとできるだけ近いウィジェットセットを最新の状態に保つために、ウィジェットセットを更新する強い動機があります。
- ウィジェットの更新が遅すぎる場合、ウィジェットを最新の状態に保つ動機を持つGoogleだけがFlutterのユーザーではありません。 Flutterのウィジェットは拡張性があり、カスタマイズ可能なので誰でもそれらを更新することができます。 更新のプルリクエストは必要はなく、またFlutter自体が更新されるのを待つ必要もありません。
- 上記の点は、新しい変更をアプリに反映させたい場合にのみ適用されます。あなたのアプリの見た目や動作に影響を与える変更を望まないなら、大丈夫です。ウィジェットはあなたのアプリの一部なので、あなたの下からウィジェットが変わらず、あなたのアプリを悪く見せたり、悪化させたりすることはありません。
- さらに、古いOSバージョンでも新しいウィジェットを使用するようにアプリケーションを書くことができます。
Other benefits
Flutterのシンプルさによって高速になりましたが、カスタマイズ性と拡張性によってパワフルになりました。
Dartにはソフトウェアパッケージのリポジトリがあり、アプリの機能を拡張することができます。たとえばFirebaseに簡単にアクセスできるようにするパッケージがいくつかあるので、「サーバレス」アプリを構築できます。外部寄稿者がReduxデータストアにアクセスできるパッケージを作成しました。また、OSに依存しない方法で、加速度計やカメラなどのプラットフォームサービスやハードウェアに簡単にアクセスできる「プラグイン」パッケージもあります。
もちろん、Flutterはオープンソースでもあり、Flutterレンダリングスタックがアプリケーションの一部であるという事実と相まって、個々のアプリケーションに必要なものをほとんどカスタマイズすることができます。下図の緑のすべてをカスタマイズすることができます。
結論(What’s new and exciting about Flutter?)
誰かがあなたにFlutterの特徴を尋ねたならば、あなたは以下のように答えることができるのです。
- リアクティブビューの利点(JavaScriptブリッジがないこと)
- 速く、滑らかで予測可能な、コードがAOTをネイティブ(ARM)コードにコンパイル
- 開発者はウィジェットとレイアウトを完全に制御できること
- 美しくカスタマイズ可能なウィジェットが付属していること
- ホットリロードを備えた素晴らしい開発ツール
- パフォーマンスが高く、多くの互換性があり、楽しいこと
(本当はもっと話をしたいところですが、)私はこのリストアップを中止したことに気がつきましたか? Flutterについて言及するときには、通常、これらのリストは最初に人々が言及するものですが、Flutterについては、これらは最も興味深いものの1つです。
Flutterは、単一のコードベースから複数のプラットフォーム用の美しく高速なアプリケーションを開発することができます。もちろん、それは与えられるべき素晴らしいことです!性能やパワーを落とさずに複数のプラットフォームにFlutterを簡単にターゲット設定できるのはカスタマイズ性と拡張性です。
Revolutionary
フラッターがなぜ「革命的」なのか、私は完全には説明しませんでした。外部の開発者がFlutterを使って構築した最初の主要アプリの1つが、アメリカ革命の時代に起こった「Hamilton:An American Musical」について公式アプリだからです。ハミルトンは、最も人気のあるブロードウェイ・ミュージカルのひとつです。
代理店によると、「わずか3ヶ月」でアプリを構築する必要があるため、Flutterを選んだと言います。彼らはそれを「革新的なショーの革命的なアプリ」と呼び、「Flutterは、美しく高性能なブランド主導のモバイルエクスペリエンスに最適な選択肢」と語りました。また、Google Developer Days会議で語られましたが、高く評価されています。
Join the REvolution!
Flutterは現在ベータ版になっています。私たちはまだそれ以上の機能を追加しており、より多くの最適化が計画されています。しかし、Googleの内部と外部の両方のグループは、すでに必要不可欠なアプリを構築するためにこれを使用しています。
Flutterに興味があるならば、それをインストールして、インストールに付属しているいくつかのサンプルアプリケーションで遊んでみてください。ステートフルなホットリロードを確認してください。
開発者ではなく、単にいくつかのアプリを見たい場合は、Flutterで作成したアプリをインストールして、外観を確認することができます。私はハミルトンアプリをお勧めしますが、他にもあります。また、FlutterアプリをコーディングしているGoogle I / Oからビデオを見る必要があります。 それは以下です。
資料
ウェブサイト
- Flutter website
- source repositories
- More helpful links
-
[Gitter channel]現在アクセスできません
動画
- Experience building the Hamilton app, at GDD
- Live coding a Flutter app, at Google I/O
- Live coding with a designer, at Google I/O
- Flutter, a new hope
- The Flutter rendering pipeline
アプリ
- Hamilton: An American Musical
-
[Flutter Gallery]見つかりません - Posse Gallery
- Friendlychat on flutter
- Friendlychat on Firebase