画像を扱う場合は、注意しないとパフォーマンスの問題が起こりやすくなります。JPG や PNG などの圧縮形式の小さなグラフィックでも、表示用にデコードされると大きなビットマップになることがあります。グラフィックの使用方法が効率的でないと、メモリの問題が発生し、アプリやデバイス上の他のアプリのパフォーマンスに影響する可能性があります。 アプリのパフォーマンスを最大限に高めるには、以下のおすすめの方法を実施してください。
画像読み込みライブラリを使用する
Coil(Kotlin ファースト プロジェクト用)や Glide(Java プロジェクト用)などの画像読み込みライブラリを使用すると、アプリの効率を向上させることができます。これらのライブラリは、画像のキャッシュ、必要に応じたグラフィックのサイズ変更、グラフィック オブジェクトのリサイクルなどを行うことで、アプリのメモリ使用量を削減します。
必要に応じて画像のサイズを変更する
ニーズに合った適切な画像サイズを使用してください。たとえば、小さなサムネイルに大きな画像を読み込むことは絶対に避けてください。代わりに、
などのメソッドを使用して、画像のリサンプリングされたバージョンを読み込みます。inSampleSize
Coil や Glide などの画像読み込みライブラリは、デフォルトでこのリサンプリングを自動的に処理します。ダウンサンプリング戦略は、
を使用して ImageLoader(Coil の場合)または DownsampleStrategy(Glide の場合)構成できます。
各種の画面サイズ向けに代替リソースを供給する
アプリで画像を提供する場合は、異なるデバイス解像度に合わせて異なるサイズのアセットを供給することを検討してください。これにより、デバイス上のアプリのダウンロード サイズを削減できます。また、低解像度のデバイスでは低解像度の画像が読み込まれるため、パフォーマンスが向上します。各種のデバイスサイズ向けに 代替ビットマップを提供する方法の詳細については、代替 ビットマップ ドキュメントを確認してください。
パディングを直接適用しない
画像にパディングを追加する必要がある場合があります。たとえば、レターボックス表示のために画像の周囲に透明な枠線を表示したい場合があります。
このような場合は、画像の寸法を変更して、パディングを画像に直接追加しないでください。代わりに、画像の寸法はそのままにして、
画面上の画像の位置を調整します。InsetDrawableまたは、画像を保持するコンポーザブルまたはビューにパディングを追加することもできます。
適切なピクセル形式を選択する
適切なピクセル形式を選択して、メモリと品質のバランスを取ります。透明度が必要ない場合は、RGB_565 を使用します。この形式では、デフォルトの ARGB_8888 形式の半分のメモリを使用します。
Glide では、DecodeFormat を使用してこれを構成できます。Coil では、
bitmapConfig プロパティを使用できます。
可能な場合はベクターを使用する
幾何学的図形で構成される画像の場合、ベクター グラフィックはビットマップよりもはるかに小さく、あらゆる表示密度に合わせてスムーズにスケーリングできます。適切な場合は、要素
を使用してグラフィックを表します。ShapeDrawable
可能な場合はビットマップを解放して再利用する
大きなグラフィック ファイルは多くのメモリを消費する可能性があります。影響を軽減するには、可能な限りグラフィック オブジェクトを解放または再利用する必要があります。
画像読み込みライブラリを使用する場合は、不要になったビットマップをライブラリのマネージド プールに解放してください。ライブラリは必要に応じてオブジェクトを再利用し、将来のニーズに対応できるようにメモリバッファを確保します。
グラフィックを手動で管理する場合は、ガベージ コレクションに依存するのではなく、
ビットマップを解放し、Bitmap.recycle
参照をすぐに破棄する必要があります。Bitmap
その他のヒントとテクニック
このセクションでは、グラフィックを処理する際にアプリのパフォーマンスを向上させるその他の方法をいくつか紹介します。
大きい画像を AAB/APK ファイルと一緒にパッケージ化しない
アプリのダウンロード サイズが大きくなる主な原因の一つとして、AAB または APK ファイル内にパッケージ化されるグラフィックがあります。APK Analyzer ツールを使用して、 必要な画像ファイルよりも大きいパッケージを作成しないようにします。サイズを小さくするか、または画像をサーバーに配置して必要なときだけダウンロードすることを検討してください。
冗長なビットマップを見つける
同じ画像のコピーが複数あると、メモリが無駄になります。Android Studio Profiler を使用して、冗長なグラフィックを特定できます。ヒープダンプ アナライザを使用してヒープダンプをキャプチャし、 [duplicate bitmaps] 設定を選択して結果をフィルタします。
ImageBitmap を使用する場合は、描画する前に prepareToDraw を呼び出す
ImageBitmap を使用する場合、GPU にテクスチャをアップロードするプロセスを開始するには、実際に描画する前に ImageBitmap#prepareToDraw() を呼び出します。これは GPU がテクスチャを準備するのに役立ち、画面上に画像を表示するパフォーマンスが向上します。ほとんどの画像読み込みライブラリはこの最適化をすでに行っていますが、ご自身で ImageBitmap クラスを扱う場合はこの点に留意してください。
Painter ではなく Int DrawableRes または URL をパラメータとしてコンポーザブルに渡す
画像の処理は複雑であるため(たとえば Bitmaps の equals
関数を記述すると計算コストが高くなります)、Painter API は
明示的には @Stable
アノテーションで安定したクラスとしてマークされていません。安定していないクラスは、データが変更されたかどうかをコンパイラが容易に推測できないため、不要な再コンポジションを発生させる可能性があります。
したがって、Painter をパラメータとしてコンポーザブルに渡すのではなく、URL またはドローアブル リソース ID をパラメータとして渡すことをおすすめします。
// Prefer this:
@Composable
fun MyImage(url: String) {
}
// Over this:
@Composable
fun MyImage(painter: Painter) {
}
あなたへのおすすめ
- 注: JavaScript がオフになっている場合はリンクテキストが表示されます
- ImageBitmap と ImageVector の比較 {:#bitmap-vs-vector}
- Compose で UI 状態を保存する
- Jetpack Compose のフェーズ