ふと、DroidKaigi 2023の配信動画を見ていたら、とても意外だったところがあったので残しておく。
(本当はQiitaにでもまとめてみようかと思ったけど、うまくまとめられそうにないのでブログに雑な感じで。)
タイトルにある通り「LaunchedEffectは若干のオーバーヘッドがあり、1フレーム遅れて実行される」というのが意外だった。
発表は「Jetpack Compose の Side-effect を使いこなす」で、誰もが一度はmediumでお世話になっているだろうSTAR_ZEROさんの発表である。
スライドでは「若干のオーバーヘッド」としか書いてないが、動画の方では「確か1フレーム遅れて実行されるのかな?」という発言もある。
スライド(P.59)
動画
まぁ普通だったらさらっと「ふーん、そうなんだぁ」と流してしまうポイントかと思うが、自分の場合、ちょうど LaunchedEffect を使った実装で処理にラグがあり、どうしたもんかと悩んでいたところだったので、この発表・発言を聞いて「そうだったのか…!」となったのである。
少し調べてみた
LaunchedEffect のオーバーヘッドについて言及されているものを調べてみたら、たしかに同じようなことを言っているXの投稿などがあるようだった。
So, this is a bit tricky. But the benefit is that DisposableEffect runs on the same frame the first composition is gonna be run. LaunchedEffect will run *after* the first successful composition. Meaning that you'd get one frame where the colors are wrong.
— Stylianos Gakis (@GakisStylianos) 2023年2月24日
実装を少し追ってみる
currentComposer.applyCoroutineContext が使われている。
おもむろにログ出力してみる。
→ [androidx.compose.ui.platform.MotionDurationScaleImpl@2b1334b, androidx.compose.runtime.BroadcastFrameClock@a15e128, JobImpl{Active}@2db3e41, AndroidUiDispatcher@b977fe6]
よくわからんが、AndroidUiDispatcher を見てみる。
Choreographer を使ってフレーム毎に処理してるっぽいことがわかった。(雰囲気理解)
まとめ
- 「LaunchedEffectは若干のオーバーヘッドがあり、1フレーム遅れて実行される」はたしかにそうなってるっぽい。
- 発表でしかわからないこともあるので、発表を聞くのは大事である。