Jetpack Compose:描画処理の周期を観測

投稿日:  更新日:

サンプルアプリを作成して、描画処理(再Compose)の周期を観測してみました。

その結果を紹介します。

※環境:Android Studio Giraffe | 2022.3.1 Patch 1
    Kotlin 1.8.10
    Compose Compiler 1.4.3

スポンサーリンク

描画処理の周期

描画処理は周期的(1/60秒)に起動されています。

周期的に実行される描画処理

これにより、画面の更新やシームレスなアニメーションを表現しています。

※詳細は「Composeによるアプリ画面の描画」を参照

スポンサーリンク

周期の観測

描画処理の周期的な起動を観測するために、サンプルアプリを作成してみました。

// 参考: 1/60[s] ≒ 16.67[ms]
private const val S_PERIOD =  5L   //  5[ms]
//private const val S_PERIOD = 20L   // 20[ms]

class MainActivity : ComponentActivity() {
    @SuppressLint("CoroutineCreationDuringComposition")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            MyApplicationTheme {
                // countの変更を追跡
                var _count = remember { mutableStateOf(0) }
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colorScheme.background
                ) {
                    FramerateCheck(count = _count.value)
                }
                // 別スレッドでcountを更新
                val _coroutineScope = rememberCoroutineScope()
                _coroutineScope.launch(Dispatchers.Default) {
                    delay(5000)
                    repeat(100) {
                        _count.value++
                        delay(S_PERIOD)
                    }
                }
            }
        }
    }
}

private var prev_tim: Long = 0L
@Composable
fun FramerateCheck(count: Int) {
    // 周期の計測
    val _crrt_tim = System.currentTimeMillis()
    Log.i(TAG, "Period = ${_crrt_tim - prev_tim}[ms] (Count = ${count})")
    prev_tim = _crrt_tim
    // コンテンツの実態
    Text(text = "Count = ${count}")
}

観測の方法は単純です。「描画処理の周期 > S_RERIOD(状態の更新間隔)」であれば、「再Composeの実行間隔 == 描画処理の周期」になります。

周期の観測

スポンサーリンク

周期の考察

観測の結果、「描画処理の周期は1/60秒である」ことが理解できます。

従って、Composable関数は「1/60秒間隔」の実行になるので、リアルタイム性のある処理を期待しても、正しく動きません。

アプリ開発者は、その点を認識しておく必要があると思います。

※参考:1/60(秒)=16.67(ms)、1/60×2(秒)=16.67×2=33.33(ms)

 【 S_PERIOD = 5(ms) 】 
Period = 17[ms] (Count = 79)	... 1
Period = 16[ms] (Count = 81)	... 2
Period = 18[ms] (Count = 84)	... 3
Period = 16[ms] (Count = 86)	... 4
Period = 17[ms] (Count = 89)	... 5
Period = 16[ms] (Count = 92)	... 6
Period = 17[ms] (Count = 94)	... 7
Period = 17[ms] (Count = 97)	... 8
Period = 16[ms] (Count = 99)	... 9
Period = 18[ms] (Count = 100)	... 10

※1~10の平均:16.6(ms)

更新の間隔=5[ms]

 【 S_PERIOD = 20(ms) 】 
Period = 16[ms] (Count = 91)	... 1
Period = 34[ms] (Count = 92)	... 2
Period = 16[ms] (Count = 93)	... 3
Period = 17[ms] (Count = 94)	... 4
Period = 33[ms] (Count = 95)	... 5
Period = 17[ms] (Count = 96)	... 6
Period = 17[ms] (Count = 97)	... 7
Period = 16[ms] (Count = 98)	... 8
Period = 34[ms] (Count = 99)	... 9
Period = 16[ms] (Count = 100)	... 10

※1,3,4,6,7,8,10の平均:16.4(ms)
 2,5,9の平均:33.7{ms)

更新の間隔=20[ms]

スポンサーリンク

関連記事:

プロジェクトのビルドで「Something went wrong while checking for version compatibility between the Compose Compiler and the Kotlin Compiler.」とメッセージを吐き、エラーになる場合があります。 既存のプロジェクトを新しくリリースされたAndroid Studioでビルドした場合に頻発します。 先日、「Giraffe|2022.3.1」がリリース(2023.07)されて、早速、ビルドをしたら発生しました。 その対処方法を説明します。 ※環境:Android Studio Giraffe | 2022.3.1 ...
表示の変わらないUI要素(Composable関数)に対して行われる再Composeは無駄な処理です。 ですので、極力排除したいところですが、表示が変わらないため、画面上からの判断が難しくなっています。 このようなとき、Layout Inspectorを利用すると、無駄な再Composeを見つけ出すことが出来ます。 ※環境:Android Studio Giraffe | 2022.3.1 Patch 1 ...
Jetpack ComposeはAndroidシステムの新たなUIフレームワークです。従来のViewシステムと、アプリ画面の描画の仕組みが異なります。 このJetpack Composeによるアプリ画面の描画について、仕組みの大枠をまとめます。 ※環境:Android Studio Giraffe | 2022.3.1 Patch 1     Kotlin 1.8.10     Compose Compiler 1.4.3 ...
Jetpack Composeは描画処理の軽量化(消費リソース量の削減)をするために、表示の変更されたUI要素のみを再Composeし、表示の変わらないUI要素をスキップします。これにより、高い表示パフォーマンスを維持しています。 しかし、スキップが正常に行われないとしても、アプリの画面に現れて来ません。なぜなら、同じ表示を無駄に繰り返すことになるからです。 アプリは動くけれど動作が鈍いならば、真っ先に疑うポイントです。不要な再Composeが行われている可能性が考えられます。 これは気付かないうちに蓄積し易い不具合です。ですので、再Composeとスキップについて理解し、予防に努めることをお勧めします。 今回は「再Composeとスキップ」について、まとめます。 ※環境:Android Studio Giraffe | 2022.3.1 Patch 1     Kotlin 1.8.10     Compose Compiler 1.4.3 ...
スポンサーリンク