性能优化 (Performance)
Compose 的性能核心在于智能跳过 (Smart Recomposition)。如果你的 App 卡顿,通常是因为 Compose 无法确定参数是否发生变化,导致进行了不必要的重组。
1. 稳定性 (Stability)
Compose 编译器会将参数类型标记为“稳定”或“不稳定”。
- 稳定 (Stable): Compose 知道该类型何时发生变化(例如
String,Int,data classwithval)。 - 不稳定 (Unstable): Compose 无法确定(例如
List,Map, 带有var属性的普通类)。
陷阱
如果 Composable 的参数包含 List<T>(这是接口,被视为不稳定),即使列表内容没变,Compose 每次也会重组该函数。
解决方案 A: 使用不可变集合
使用 Kotlinx Immutable Collections 库。
kotlin
// build.gradle
implementation("org.jetbrains.kotlinx:kotlinx-collections-immutable:0.3.7")
// 使用 PersistentList 替代 List
@Composable
fun ItemList(items: PersistentList<String>) { ... }解决方案 B: 强跳过模式 (Strong Skipping)
从 Compose Compiler 1.5.4+ 开始,支持强跳过模式。它允许跳过参数不稳定的 Composable(通过比较实例引用)。
在 Kotlin 2.0 中,强跳过模式默认开启。
解决方案 C: @Stable / @Immutable 注解
手动告诉编译器:“相信我,这个类是稳定的”。
kotlin
@Stable
data class UiState(
val items: List<String> // 普通 List 默认是不稳定的
)2. defer read (推迟读取)
尽可能推迟状态的读取时机,使其在 Layout 或 Draw 阶段读取,而不是 Composition 阶段。
kotlin
// 每次 scroll 变化,都会触发 Composition 阶段重组
val scroll = scrollState.value
Box(Modifier.offset(y = scroll.dp))kotlin
// 使用 Lambda,在 Layout 阶段才读取 scroll
// Composition 阶段不会因 scroll 变化而重组
Box(Modifier.offset { IntOffset(0, scrollState.value) })3. 发布构建 (Release Build)
切勿在 Debug 模式下衡量性能!
Compose 在 Debug 模式下包含大量断言和调试代码,性能远低于 Release 模式。并且 R8 (ProGuard) 能够大幅优化 Compose 运行时的代码。
检查重组
在 Android Studio 中,启用 Layout Inspector,可以查看每个 Composable 的重组次数和跳过次数。这对于排查性能瓶颈至关重要。