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

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

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

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

ただし、コーディング上の誤りがあると、Compose が安全にスキップできるフェーズを判別するのが難しくなる場合があります。その場合、Compose は 3 つのフェーズすべてを実行するため、UI の速度が低下する可能性があります。そのため、パフォーマンスに関するおすすめの方法の多くは、Compose が実施する必要がないフェーズをスキップできるようにすることに重点を置いています。

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

一般原則

一般的にパフォーマンスを改善する原則はいくつかあります。

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

参考情報