Gojek Raditya Gumay Jan 20, 2026

The Silent Performance Killer: How a Single Lambda Nearly Destroyed My Compose UI

Article Summary

Raditya Gumay from GoTo discovered his navigation UI was recomposing 60+ times per minute. The culprit? A single lambda inside a data class that looked completely innocent.

While building navigation controls for GoTo's app, a Sr. Principal Engineer uncovered a subtle Jetpack Compose performance trap. Despite all state appearing stable in logs, the UI was recomposing every single second, wasting CPU cycles and draining battery.

Key Takeaways

Critical Insight

A data class containing a lambda caused continuous recomposition because Compose saw each lambda recreation as a state change, fixed by implementing type-based equality or separating state from actions entirely.

The article reveals why multiple common fixes (removing data keyword, using remember, custom equals with lambda comparison) all failed before finding the right solution.

About This Article

Problem

Raditya Gumay found that CartoNavigationControls was recomposing every second even though the collected state had identical hash codes. This turned out to be a stability contract violation in Jetpack Compose.

Solution

He added custom equals() and hashCode() methods that skip lambda properties and used the @Stable annotation. This switched the comparison to type-based equality instead of checking the lambda functions structurally.

Impact

The fix cut unnecessary recompositions from 60+ per minute down to nearly zero, restored 60fps rendering, and reduced CPU usage and battery drain from wasted recomposition work during navigation.