Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Google IO 2022 Jetpack Composeのパフォーマンス 社内LT会資料

Ebe2290af44f0f8b47a80a6af9b807ad?s=47 ginyolith
July 08, 2022
370

Google IO 2022 Jetpack Composeのパフォーマンス 社内LT会資料

Sansan株式会社 技術本部 MobileApplicationGroupで行われた社内LT会の資料です。

Ebe2290af44f0f8b47a80a6af9b807ad?s=128

ginyolith

July 08, 2022
Tweet

Transcript

  1. Google I/O 2022 社内LT会 Jetpack Compose のパフォーマンス 2022/06/24 赤城 史哉

  2. 話すこと - パフォーマンス計測の前に - Compose の段階 - 落とし穴 1 :

    LazyList Key - 落とし穴 2 : derivedStateOf - 落とし穴 3 : Modifier.drawBhind
  3. パフォーマンス計測の前に - リリースモードでビルドし、 R8 を使用する - デバッグの体験を向上させる、デバッグモードではパフォーマンスの最適化が行われない。 - R8 で冗長なコードが削除される

    - Layout inspector の recomposition count が便利 - 動作環境 - Android Studio Electric Eel - Jetpack compose version : 1.2.0-alpha03 or higher.
  4. Layout inspector の recomposition count Recompositionを スキップした回数 Recompose回数

  5. Composeの段階 - Composition / コンポジション - UI の構成を決める。ツリーを作成。 - Layout

    / レイアウト - UI の配置、大きさを決める。 - Drawing / 描画 - UI 要素をキャンバス(通常はデバイス画面)に描画
  6. LazyList Key // Do not @Composable fun NotesList(notes: List<Note>) {

    LazyColumn { items( items = notes ) { note -> NoteRow(note) } } } Item 1 Item 2 Item 3 Item 4 Item 5 Item 2 Item 3 Item 4 Item 5 - LazyColumn の item のある要素が削除されると、以下の Item 全てが Recompose され てしまう
  7. LazyList Key Item 1 Item 2 Item 3 Item 4

    Item 5 Item 2 Item 3 Item 4 Item 5 - LazyColumn に Key を設定すれば、 item の index が変わっても適切に recomposition が制御されます。 // Do @Composable fun NotesList(notes: List<Note>) { LazyColumn { items( items = notes, key = { note -> // Return a stable, // unique key for the note note.id } ) { note -> NoteRow(note) } } }
  8. LazyList Key - Key が重複すると、 Exception が吐かれるので注意

  9. derivedStateOf // Do not val listState = rememberLazyListState() LazyColumn(state =

    listState) { // ... } val showButton = listState.firstVisibleItemIndex > 0 AnimatedVisibility(visible = showButton) { ScrollToTopButton() } Scrollをする度に、Scrollしている最中の全ての フレームでRecomposeされる
  10. derivedStateOf - derivedStateOf で listState など高い頻度で更新される state を wrap すると、

    必要な時のみ recomposition されるように制御出来る。 // Do val listState = rememberLazyListState() LazyColumn(state = listState) { // ... } val showButton by remember { derivedStateOf { listState.firstVisibleItemIndex > 0 } } AnimatedVisibility(visible = showButton) { ScrollToTopButton() } この条件式の結果が変わったタイミングでのみ Recomposeされる
  11. Modifier.drawBhind を使って不要な Stepをスキップ - animateColorBetween で color が変わるたびに Recompose されてしまう

    // Here, assume animateColorBetween() is a function that swaps between // two colors val color by animateColorBetween(Color.Cyan, Color.Magenta) Box(Modifier.fillMaxSize().background(color)) 2色の間でアニメーションされる架空の関数 毎フレームcolorが更新される
  12. Modifier.drawBhind を使って不要な Stepをスキップ - drawBehind を使うと、 color に変更があっても composition と

    layout はスキップされ、 draw だけ行われる。 - layout inspector では draw の実行のみだと recomposition として扱われなかった。 val color by animateColorBetween(Color.Cyan, Color.Magenta) Box( Modifier .fillMaxSize() .drawBehind { drawRect(color) } )
  13. 参考資料 - Compose のパフォーマンス - https://developer.android.google.cn/jetpack/compose/performance?hl=ja - Jetpack Compose の一般的なパフォーマンスの落とし穴

    / Google IO 2022 - https://io.google/2022/program/213421b6-9873-464f-9b36-38eeb232a854/intl/ja/ - Compose tooling / Layout Inspector - https://developer.android.com/jetpack/compose/tooling#layout-inspector