$npx -y skills add skydoves/compose-performance-skills --skill visualizing-recomposition-cascadesUse this skill to drive the active investigation features of the skydoves/compose-stability-analyzer IntelliJ / Android Studio plugin: the static Recomposition Cascade visualizer that walks the call graph from a root @Composable, and the live Recomposition Heatmap that stream
| 1 | # Visualizing Recomposition Cascades — static blast radius and live heatmap inside the IDE |
| 2 | |
| 3 | Passive gutter icons answer "is this composable skippable" (covered by `../using-stability-analyzer-ide-plugin/SKILL.md`). The active investigation tools answer two harder questions. The Cascade visualizer walks the static call graph from a root `@Composable` and shows what else might recompose if the root recomposes. The Live Heatmap subscribes to the device's logcat and renders the actual recomposition counts as block inlays above each instrumented composable in the editor. Together they close the loop between static analysis and runtime evidence. |
| 4 | |
| 5 | Both features live inside the same IntelliJ plugin and surface through the right-anchored **Compose Stability Analyzer** tool window, which has three tabs: **Explorer**, **Cascade**, and **Heatmap**. |
| 6 | |
| 7 | ## When to use this skill |
| 8 | |
| 9 | - The developer asks "what gets dragged in if I change this composable" — use the Cascade tab. |
| 10 | - The developer asks "how many times did this recompose during that scroll" or "which composable is hot during this animation" — use the Heatmap tab. |
| 11 | - Triaging a recomposition spike surfaced by `../../recomposition/debugging-recompositions/SKILL.md` and needing the call-site context. |
| 12 | - Preparing a refactor and wanting the blast radius before touching a shared composable. |
| 13 | - The user mentions the Cascade tab, the Heatmap tab, recomposition inlays, **Analyze Recomposition Cascade**, **Toggle Recomposition Heatmap**, or **Clear Recomposition Data**. |
| 14 | |
| 15 | ## When NOT to use this skill |
| 16 | |
| 17 | - Pure source-level diagnosis. The gutter icons and the `UnstableComposable` inspection from `../using-stability-analyzer-ide-plugin/SKILL.md` are enough. |
| 18 | - CI gating against stability regressions. Use `../enforcing-stability-in-ci/SKILL.md`. |
| 19 | - Full release-grade scroll/startup measurement with FrameTimingMetric. Use `../../measurement/generating-baseline-profiles/SKILL.md`. Toggle the heatmap **off** before such runs. |
| 20 | - Conceptual questions about how the compiler classifies a type. Use `../understanding-stability-inference/SKILL.md`. |
| 21 | |
| 22 | ## Prerequisites |
| 23 | |
| 24 | - The IDEA plugin from `../using-stability-analyzer-ide-plugin/SKILL.md` already installed and the **Compose Stability Analyzer** tool window visible in the right rail. |
| 25 | - For the **Cascade** workflow: nothing extra; it is pure static analysis on the open project's PSI. |
| 26 | - For the **Heatmap** workflow: |
| 27 | - At least one composable annotated with `@TraceRecomposition` (cross-link `../../measurement/tracing-recompositions-at-runtime/SKILL.md` for the runtime setup). |
| 28 | - An Android device or emulator connected via ADB. |
| 29 | - The app installed and running. |
| 30 | - `ComposeStabilityAnalyzer.setEnabled(true)` called in `Application.onCreate` (gated on `BuildConfig.DEBUG` or a dedicated flag — see `../../measurement/tracing-recompositions-at-runtime/SKILL.md`). |
| 31 | |
| 32 | ## Workflow A — Cascade visualizer |
| 33 | |
| 34 | ### A1. Place the caret inside a `@Composable` |
| 35 | |
| 36 | The action **Analyze Recomposition Cascade** (id `com.skydoves.compose.stability.idea.cascade.AnalyzeCascadeAction`) is enabled only when the caret is inside a `@Composable` function. It is registered in the Editor popup; right-click anywhere inside the composable body to surface it. |
| 37 | |
| 38 | ### A2. Run the action |
| 39 | |
| 40 | Right-click → **Analyze Recomposition Cascade**. The right-anchored **Compose Stability Analyzer** tool window opens to the **Cascade** tab and renders a tree rooted at the selected function. |
| 41 | |
| 42 | Internals to know when triaging the result: |
| 43 | |
| 44 | - The walk starts from the selected `KtCallExpression` and descends into call targets resolved via `resolveMainReference()`. |
| 45 | - Maximum recursion depth is capped at 10 levels, so cascades from very wide composables |