見出し画像

【Flutter】ビルドモード(Debug, Release, Profile)ちょろっとメモ

■確認環境
・Windows11
・Android Studio (version 2021.1)
・Flutter 2.10.4
・Dart 2.16.2
・Flutterプロジェクト新規作成時に生成されるカウンターアプリのコードで確認
・Androidアプリでのみ確認


ビルドモード種別

Flutterのビルドモードには『Debug』、『Release』、『Profile』の3種類がある。

・Use debug mode during development, when you want to use hot reload.
・Use profile mode when you want to analyze performance.
・Use release mode when you are ready to release your app.

■google翻訳
・ホットリロードを使用する場合は、Debugモードを使用してください。
・パフォーマンスを分析する場合は、Profileモードを使用します。
・アプリをリリースする準備ができたら、Releaseモードを使用します。

https://docs.flutter.dev/testing/build-modesから一部抜粋

[Build]->[Flutter]->[Build APK] ⇒Releaseモード

ビルド時のログ

※デフォルト設定が『Releaseモード』になっているだけで、もしかしたら、他のモードでもビルドできるのかもしれない。

[Run]で実行 ⇒Debugモード

ビルド時のログ

[Debug]で実行 ⇒Debugモード

ビルド時のログ

[Run]実行時は、ブレーク張ったり、変数の中身見たり、コールスタックを見たりすることができないので、Debugモードではないと思っていたけど、
[Run]で実行時はホットリロードができるので、『ホットリロードを使用する場合は、Debugモードを使用してください。』と説明がある通り、Debugモードでのビルドになるみたい。


JITとAOT

コンピーターがプログラムを実行するためには機械語にする必要があります。それがコンパイルです。

AOTコンパイルは事前にコンパイルしておき、それを配置して実行します。そのため、配置する前のコンパイル時間がかかる代わりに、実行時に高速になります。

JITコンパイルはプログラムを配置してから、実行時にコンパイルしながら動作します。そのため、配置まではまったく時間がかからず、代わりに実行時は低速になります。

DartはこのAOTとJITの両方をサポートしているので、両方の利点を上手に扱うことができます。

Flutterでは、debugモードのときはJITコンパイルしているので、ホットリロードが可能になっています。このため開発者は、高速な開発サイクルが可能になります。

releaseモードのときはAOTコンパイルをしているので、事前に最適化された機械語になり、ユーザーにAndroidやiOSのネイティブ操作時とほとんど変わらない高速な体験を与えることが可能になります。

書籍:『基礎から学ぶFlutter(著:石井幸次)』 SECTION-009 Dartの特徴 JITとAOT

デバッグモード(JITコンパイル)は、Dartコードを一つのバイナリデータ(flutter_assets/kernel_blob.bin)にして固めて、Flutter Engine初期化時にDart VMにロードする。

『kernel_blob.bin』の在りか

①:debugモードでビルドすると以下apkファイルが生成される。
  \build\app\outputs\apk\debugapp-debug.apk

②:debugapp-debug.apkファイルを解凍する。
        (apkファイルはzipツールなどで解凍可能)

③:apkファイルを解凍すると『flutter_assets/kernel_blob.bin』がある。

『flutter_assets/kernel_blob.bin』をテキストエディタで開いてみると、ベタにDartのコードが含まれている。これが、アプリ起動時に、Dart VM上にロードされて、必要に応じてコンパイルされて実行されるということなのか。

『flutter_assets/kernel_blob.bin』の中身

『kernel_blob.bin』はReleaseモードには存在しない。

releaseモードで作成したapkファイルを同様に解凍してみたところ、『kernel_blob.bin』は存在しなかった。

だけど、releaseモードのときは『AOTコンパイルをしているので、事前に最適化された機械語になり』とのことなので、apkファイル内のどこかに機械語になったdartコードが存在するはずである。

解凍したapkファイル内をDartコードに含まれる文字列
『You have pushed the button this many times:』で検索してみたところ、以下ファイルに存在した。

lib\arm64-v8a\libapp.so
lib\armeabi-v7a\libapp.so
lib\x86_64\libapp.so

lib\arm64-v8a\libapp.soの中身

尚、『libapp.so』は、Debugモードでビルドしたapkには存在しなかった。
『*.so』ファイルは、UNIX系OSで使用される共有ライブラリのファイル形式になり、Releaseモードでビルドした場合は、Dartコードは、『kernel_blob.bin』ではなく、『libapp.so』に纏められている模様。

今のところの自分の認識としては以下となる。

・Debugモードでのビルド時、Dartコードは、『kernel_blob.bin』に纏められて、起動時にDart VMに読み込まれる。そして実行時に、コンパイルされて機械語に翻訳しながら動作する。

・Releaseモードでのビルド時、Dartコードは、『libapp.so』に纏められる。
『libapp.so』は既に機械語に翻訳された状態なので、実行時にいちいち、コンパイルして機械語に翻訳する必要はないので、Debugモード時に比べると高速に動作する。(ネイティブコードで組んだAndroidアプリと同等のパフォーマンスとなる。)

参考ページ


この記事が気に入ったらサポートをしてみませんか?