compose-performance-audit by new-silvermoon/awesome-android-agent-skills
npx skills add https://github.com/new-silvermoon/awesome-android-agent-skills --skill compose-performance-audit对 Jetpack Compose 视图性能进行端到端审计,涵盖从检测和基准测试到根因分析及具体修复步骤。
收集:
重点关注:
LazyColumn/LazyRow 中(key 频繁变动、缺少键)。remember、不稳定的类、lambda 表达式。广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
SubcomposeLayout提供:
解释如何收集数据:
索取:
重要提示:确保在启用 R8 的发布版构建上进行性能分析。调试版构建有显著的开销。
优先排查可能的 Compose 问题根源:
key 频繁变动、基于索引的键)。remember:导致每次重组时都重新创建。Modifier.size() 约束。根据跟踪记录/布局检查器提供的证据总结发现。
应用针对性修复:
@Stable 或 @Immutable 注解。LazyColumn/LazyRow 项使用稳定、唯一的 ID。derivedStateOf、基于 lambda 的修饰符或 Modifier.drawBehind。remember { } 或 remember(key) { } 包装。key() 来控制标识。// 错误:每次重组都创建新的 lambda 实例
Button(onClick = { viewModel.doSomething(item) }) { ... }
// 正确:使用 remember 或方法引用
val onClick = remember(item) { { viewModel.doSomething(item) } }
Button(onClick = onClick) { ... }
// 错误:每次重组都进行排序
@Composable
fun ItemList(items: List<Item>) {
val sorted = items.sortedBy { it.name } // 每次重组都运行
LazyColumn { items(sorted) { ... } }
}
// 正确:使用带键的 remember
@Composable
fun ItemList(items: List<Item>) {
val sorted = remember(items) { items.sortedBy { it.name } }
LazyColumn { items(sorted) { ... } }
}
// 错误:基于索引的标识(列表变化时导致重组)
LazyColumn {
items(items) { item -> ItemRow(item) }
}
// 正确:基于稳定键的标识
LazyColumn {
items(items, key = { it.id }) { item -> ItemRow(item) }
}
// 错误:不稳定(包含 List,而 List 不稳定)
data class UiState(
val items: List<Item>,
val isLoading: Boolean
)
// 正确:如果确实不可变,标记为 Immutable
@Immutable
data class UiState(
val items: ImmutableList<Item>, // kotlinx.collections.immutable
val isLoading: Boolean
)
// 错误:在组合阶段读取状态(重组整个树)
@Composable
fun AnimatedBox(scrollState: ScrollState) {
val offset = scrollState.value // 每次滚动都重组
Box(modifier = Modifier.offset(y = offset.dp)) { ... }
}
// 正确:将状态读取延迟到布局/绘制阶段
@Composable
fun AnimatedBox(scrollState: ScrollState) {
Box(modifier = Modifier.offset {
IntOffset(0, scrollState.value) // 在布局阶段读取
}) { ... }
}
// 错误:每次重组都创建新的 Modifier 链
Box(modifier = Modifier.padding(16.dp).background(Color.Red))
// 正确(对于动态修饰符):记住修饰符
val modifier = remember { Modifier.padding(16.dp).background(Color.Red) }
Box(modifier = modifier)
| 类型 | 默认稳定? | 修复方法 |
|---|---|---|
基本类型(Int、String、Boolean) | 是 | 不适用 |
具有稳定字段的 data class | 是* | 确保所有字段稳定 |
List、Map、Set | 否 | 使用 kotlinx 的 ImmutableList |
具有 var 属性的类 | 否 | 如果外部稳定,使用 @Stable |
| Lambda 表达式 | 否 | 使用 remember { } |
请用户:
如果提供了数据,总结变化(重组计数、掉帧、卡顿)。
提供:
每周安装量
178
代码仓库
GitHub 星标数
565
首次出现
2026年1月27日
安全审计
安装于
opencode157
codex153
claude-code133
gemini-cli128
github-copilot121
cursor108
Audit Jetpack Compose view performance end-to-end, from instrumentation and baselining to root-cause analysis and concrete remediation steps.
Collect:
Focus on:
LazyColumn/LazyRow (key churn, missing keys).remember, unstable classes, lambdas).SubcomposeLayout misuse).Provide:
Explain how to collect data:
Ask for:
Important : Ensure profiling is done on a release build with R8 enabled. Debug builds have significant overhead.
Prioritize likely Compose culprits:
key churn, index-based keys).remember causing recreations on every recomposition.Modifier.size() constraints.Summarize findings with evidence from traces/Layout Inspector.
Apply targeted fixes:
@Stable or @Immutable annotations on data classes.LazyColumn/LazyRow items.derivedStateOf, lambda-based modifiers, or Modifier.drawBehind.remember { } or remember(key) { }.key() to control identity.// BAD: New lambda instance every recomposition
Button(onClick = { viewModel.doSomething(item) }) { ... }
// GOOD: Use remember or method reference
val onClick = remember(item) { { viewModel.doSomething(item) } }
Button(onClick = onClick) { ... }
// BAD: Sorting on every recomposition
@Composable
fun ItemList(items: List<Item>) {
val sorted = items.sortedBy { it.name } // Runs every recomposition
LazyColumn { items(sorted) { ... } }
}
// GOOD: Use remember with key
@Composable
fun ItemList(items: List<Item>) {
val sorted = remember(items) { items.sortedBy { it.name } }
LazyColumn { items(sorted) { ... } }
}
// BAD: Index-based identity (causes recomposition on list changes)
LazyColumn {
items(items) { item -> ItemRow(item) }
}
// GOOD: Stable key-based identity
LazyColumn {
items(items, key = { it.id }) { item -> ItemRow(item) }
}
// BAD: Unstable (contains List, which is not stable)
data class UiState(
val items: List<Item>,
val isLoading: Boolean
)
// GOOD: Mark as Immutable if truly immutable
@Immutable
data class UiState(
val items: ImmutableList<Item>, // kotlinx.collections.immutable
val isLoading: Boolean
)
// BAD: State read during composition (recomposes whole tree)
@Composable
fun AnimatedBox(scrollState: ScrollState) {
val offset = scrollState.value // Recomposes on every scroll
Box(modifier = Modifier.offset(y = offset.dp)) { ... }
}
// GOOD: Defer state read to layout/draw phase
@Composable
fun AnimatedBox(scrollState: ScrollState) {
Box(modifier = Modifier.offset {
IntOffset(0, scrollState.value) // Read in layout phase
}) { ... }
}
// BAD: Creates new Modifier chain every recomposition
Box(modifier = Modifier.padding(16.dp).background(Color.Red))
// GOOD for dynamic modifiers: Remember the modifier
val modifier = remember { Modifier.padding(16.dp).background(Color.Red) }
Box(modifier = modifier)
| Type | Stable by Default? | Fix |
|---|---|---|
Primitives (Int, String, Boolean) | Yes | N/A |
data class with stable fields | Yes* | Ensure all fields are stable |
List, Map, Set | No | Use from kotlinx |
Ask the user to:
Summarize the delta (recomposition count, frame drops, jank) if provided.
Provide:
Weekly Installs
178
Repository
GitHub Stars
565
First Seen
Jan 27, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
opencode157
codex153
claude-code133
gemini-cli128
github-copilot121
cursor108
Swift Actor 线程安全持久化:构建离线优先应用的编译器强制安全数据层
1,700 周安装
股票智能分析工具 - 支持A股/港股/美股技术面分析与AI决策建议
832 周安装
Python Excel自动化:openpyxl库操作XLSX文件教程,创建编辑格式化电子表格
868 周安装
数据分析技能:使用DuckDB高效分析Excel/CSV文件,支持SQL查询与统计摘要
867 周安装
Oracle到PostgreSQL迁移测试项目脚手架 - 集成测试基础设施搭建指南
889 周安装
Oracle到PostgreSQL存储过程迁移工具:自动翻译PL/SQL为PL/pgSQL
888 周安装
Oracle到PostgreSQL迁移集成测试规划指南 | 数据库迁移测试自动化
890 周安装
ImmutableListClasses with var properties | No | Use @Stable if externally stable |
| Lambdas | No | Use remember { } |