I have written a small utility class that tells me...
# compose
s
I have written a small utility class that tells me what the frame rate is for my composables that are wrapped inside this
FrameRateTracker
I'm using this to measure and track framerate for our composables and we report them using our telemetry events. This is to improve UI rendering performance based on the analytics. Can someone look at the code and tell me if I'm missing something that's supposed to be an edge case?
Copy code
@Composable
fun FrameRateTracker(modifier: Modifier = Modifier) {
    var fps by remember { mutableStateOf(0f) }
    var frameCount by remember { mutableStateOf(0) }
    var lastFrameTime by remember { mutableStateOf(0L) }

    // This effect will run when the composable enters the composition
    // and stop when it leaves the composition
    LaunchedEffect(Unit) {
        while (isActive) {
            withFrameNanos { frameTimeNanos ->
                if (lastFrameTime != 0L) {
                    val frameTime = frameTimeNanos - lastFrameTime
                    frameCount++
                    
                    if (frameTime >= 1_000_000_000) { // 1 second in nanoseconds
                        fps = frameCount.toFloat() * 1_000_000_000 / frameTime
                        frameCount = 0
                    }
                }
                lastFrameTime = frameTimeNanos
            }
        }
    }

    Box(modifier = modifier) {
        Text(
            text = "FPS: %.1f".format(fps),
            color = Color.Red,
            fontSize = 16.sp
        )
    }
}
1
r
What are you trying to measure exactly?
a
As I see it now you’re triggering recompositions.
s
@romainguy I'm trying to report slow and frozen frame count to our performance tracking.
@Arjan van Wieringen This function is supposed to calculate the frame rate of the composable that it wraps.
r
FPS is not a good metric for this. If you're on Android you should look into JankStats or frame metrics