Agent Skills
› chrisbanes/skills
› compose-recomposition-performance
compose-recomposition-performance
GitHub用于诊断 Jetpack Compose 重组性能问题,通过参数稳定性、状态读取时机及跨阶段反向写入三个维度定位瓶颈,并指导用户路由至对应的专项技能进行深度修复。
Trigger Scenarios
调查 Jetpack Compose 重组性能
分析可跳过/重启的组件
检查编译器报告或 composables.txt
排查 Layout Inspector 中的重组计数异常
检测跨阶段的 snapshot state 反向写入
Install
npx skills add chrisbanes/skills --skill compose-recomposition-performance -g -y
SKILL.md
Frontmatter
{
"name": "compose-recomposition-performance",
"description": "Use when investigating Jetpack Compose recomposition performance, skippable\/restartable composables, composables.txt or compiler reports, Layout Inspector recomposition counts, back-writing snapshot state across phases, or frame-rate State reads in composition vs layout\/draw, and it is not yet clear whether the cause is parameter stability, deferred reads, or cross-phase back-writing."
}
Compose recomposition performance
Router only — deep fixes live in focused skills below.
Three axes
- Parameter stability / skipping — can Compose skip this restartable composable; are arguments stable and comparable?
- Where
Stateis read — is frame-rateStateread during composition vs layout/draw? - Back-writing across phases — does a later phase write snapshot state that invalidates an earlier phase? Examples: map/list mutation during composition that re-invalidates the same composition;
onSizeChanged(layout phase) writing state read by a sibling in composition.
Axes 2 and 3 often overlap (a sibling reading measured size in composition is both a deferred-read violation and a layout → composition back-write). Axis 1 is independent.
Route here → focused skill
| Primary suspicion | Next skill |
|---|---|
Skipping, unstable params, compiler/composables.txt churn |
compose-stability-diagnostics |
Frame-rate State read phase (composition vs layout/draw) |
compose-state-deferred-reads |
putAll / map rebuild / cross-row height(state) during composition |
compose-state-deferred-reads — § back-writing |
| Focus-driven side work in composable body | compose-side-effects — snapshotFlow |
| Evidence for multiple axes | Apply matching skills in parallel |
Review order
- Reproduce one transition (focus move, insertion, scroll) and note which composables recompose.
- If counts spike on unchanged lazy items, check back-writing (composition mutations and cross-row measurement) before blaming stability.
- If counts climb every frame during scroll/animation, check deferred reads.
- If skipping fails despite stable data, check parameter stability and compiler reports.
- Re-measure after each fix.
False leads
These changes often do not reduce recomposition count:
| Attempt | Why it fails |
|---|---|
remember(index) { isFirstRow(index) } instead of inline when (index) |
Same inputs; no skipping benefit |
| Identity cache for read-only derived maps | Can serve stale overlays; remember(keys) is enough |
mutableIntStateOf + layout modifier on both measured and sibling rows |
Sibling still reads size in composition unless measure-only |
Forcing Exactly(1) on both rows in focus-move tests |
One row often correctly recomposes 0 times |
| Hoisting without stabilizing lambda captures | New lambda instance each frame still defeats skipping |
When NOT to apply
- Recomposition tracks real data changes, or the bug is correctness not cost.
- No profiler / compiler signal suggests a problem.
Related
compose-state-authoring— authoringmutableState*safely.
Version History
- 2026.7.21 Current 2026-07-24 12:25


