Compose のフェーズとパフォーマンス

Compose がフレームを更新する際、次の 3 つのフェーズを経由します。

  • コンポジション: Compose は表示する内容を決定します。コンポーズ可能な関数を実行し、UI ツリーを構築します。
  • レイアウト: Compose は、UI ツリー内の各要素のサイズと配置を決定します。
  • 描画: Compose は実際に個々の UI 要素をレンダリングします。

Compose は、必要ない場合にこれらのフェーズのいずれかをインテリジェントにスキップできます。たとえば、1 つのグラフィック要素が、同じサイズの 2 つのアイコン間で入れ替わるとします。この要素はサイズが変更されず、UI ツリーの要素が追加または削除されていないため、Compose はコンポジション フェーズとレイアウト フェーズをスキップして、この 1 つの要素を再描画できます。

ただし、コーディングミスがあると、Compose が安全にスキップできるフェーズを把握するのが難しくなる可能性があります。その場合、Compose は 3 つのフェーズすべてを実行するため、UI の速度が低下する可能性があります。したがって、パフォーマンスに関するベスト プラクティスの多くは、Compose が不要なフェーズをスキップできるようにすることです。

詳しくは、Jetpack Compose のフェーズのガイドをご覧ください。

一般的な原則

一般的に、パフォーマンスを向上させるには、次の 2 つの大原則に従う必要があります。

  • 可能な限り、コンポーズ可能な関数から計算を移動します。 UI が変更されるたびに、コンポーズ可能な関数の再実行が必要になる場合があります。コンポーザブルに追加したコードは、アニメーションのフレームごとに再実行されます。コンポーザブルのコードは、UI の構築に必要なもののみに制限します。
  • 状態の読み取りを可能な限り延期する。状態の読み取りを子コンポーザブルまたは後のフェーズに移動することで、再コンポーズを最小限に抑えるか、コンポジション フェーズを完全にスキップできます。これを行うには、頻繁に変化する状態については状態値の代わりにラムダ関数を渡し、頻繁に変化する状態を渡すときはラムダベースの修飾子を優先します。この手法の例については、ベスト プラクティスに従う可能な限り読み取りを延期するのセクションをご覧ください。

その他のリソース