初めに
こんにちは!Flutterエンジニア(自称)の柴田です。
Flutterは、UIレンダリングエンジンとしてSkiaを採用しています。
しかし、Skiaにはパフォーマンスの問題があり、Flutterはバージョン3.0.0で「Impeller」というUIレンダリングエンジンを実験的に導入しました。
今回はこの「Impeller」を試してみます。
「Skia」とは
Skiaは2Dグラフィックスライブラリーです。
特徴として以下の点があげられます。
- オープンソース
- Googleが開発
- C++を使用
- マルチプラットフォームに対応
Chrome、Android、.NET MAUI(Xamarin.Forms)、Compose Multiplatformなど多くの環境で採用されています。
余談: Xamarinは今後サポート終了し.NET MAUIに引き継がれる予定です。https://dotnet.microsoft.com/ja-jp/platform/support/policy/xamarin
FlutterでもUIレンダリングエンジンとしてSkiaを採用しています。(Flutter WebはSkiaのWebAssembly版であるCanvasKitを使用)
Skiaの問題点
初回起動時のパフォーマンスが悪い
Skiaでは、アプリ初回起動時にシェーダーコンパイルが行われるため、初回起動時のパフォーマンスが良くありません。(60FPSを下回るなど)
Andoridはコンパイルの結果が永続化されるため、パフォーマンスが悪いのはアプリインストール後の起動時のみですが、iOSはタスクキルすると廃棄されるため、アプリを起動するたびにパフォーマンスが悪くなります。
Skiaにはこのシェーダーコンパイルを事前にしておくSkSL(Skia Shader Language) warmupという機能があります。これは、事前にSkSL でシェーダーをキャプチャし、それをアプリにパッケージ化することで初回起動時のコンパイルを軽減するものです。しかし、これはアプリを変更するたびに全てのシェーダーをキャプチャする必要があり、開発者の負担が大きいという問題があります。また、キャプチャしたシェーダーが他の端末で使用できる保証がありません。
新しいエンジン「Impeller」とは
これらSkiaのパフォーマンス問題はFlutter公式でも認識しており、グラフィックバックエンドの書き換えをおこなっています。それが「Impeller」です。
「Impeller」はFlutterのためのレンダリングランタイムです。
特徴としては以下の点があげられます。
- 全てのシェーダーのコンパイルをビルド時にオフラインで実行
- モダンなグラフィックスAPIを効果的に使用
- MetalやVulkanなどの利用可能な機能を使用する(依存はしない)
- 並行処理を効果的に使用
- 必要なら単一フレームワークロードを複数スレッドに分配して処理する
現在Impellerが使用できるのはiOSとAndroidのみです。
「Impeller」を使ってみる
重いと噂のアプリでパフォーマンスの比較を行います。ページ遷移時のレンダリング速度をDevToolsで計測します。
実行環境
- MacBook Pro (13-inch, M1, 2020)
- Flutter 3.0.4
- Simulator Version 13.4.1 (977.2)
- iPhone 13 Pro (iOS15.5)
結果
シェーダーコンパイルにかかる時間の結果です。
Skiaは162.5msかかってるのに対し、Impellerは22.1msとSkiaに比べ7倍以上高速になっています。
体感でもカクつきが明らかに減っています。
しかし、なお60FPSを出すのに必要な16msを上回っています。
今回の計測はdebug buildなのでrelease buildにすればもっとパフォーマンスが良くなると思います。
1 2 |
# Skia flutter run |
1 2 3 |
# Impeller flutter run --enable-impeller |
終わりに
今回は新たなシェーダーレンダリングエンジンのImpellerを試してみました。Impellerを用いることで、Skiaに比べ7倍以上のパフォーマンスが出ることを確認できました。ImpellerがStableになることを楽しみに今後のアップデートに注目します。
みなさんもFlutterで快適な開発体験を!!