avoiding-subcomposition-pitfalls

Diagnoses and fixes SubcomposeLayout, BoxWithConstraints, and Scaffold misuse causing extra measure passes in Jetpack Compose.

Updated May 31, 2026
One-click install
npx skills add https://github.com/decoutkhanqindev/Lich-Viet-Loc-Phat --skill avoiding-subcomposition-pitfalls-decoutkhanqindev
Or copy as Structured Prompt for Agent▼
Please help me install this Agent Skill.
Skill: avoiding-subcomposition-pitfalls
Source: https://github.com/decoutkhanqindev/Lich-Viet-Loc-Phat/tree/main/.claude/skills/avoiding-subcomposition-pitfalls
Command: npx skills add https://github.com/decoutkhanqindev/Lich-Viet-Loc-Phat --skill avoiding-subcomposition-pitfalls-decoutkhanqindev

SYSTEM DOCUMENTATION & REQUIREMENTS

What problem does it solve? Jetpack Compose screens built with SubcomposeLayout, BoxWithConstraints, or nested Scaffold pay hidden composition costs during the measure phase, producing extra measure passes, slow first frames, and scroll jank that developers struggle to trace. ## Core Features & Use Cases - Misuse Detection: Identifies BoxWithConstraints blocks that only read maxWidth/maxHeight, nested Scaffolds, and BoxWithConstraints inside LazyColumn items. - Cheaper Replacements: Migrates unjustified subcomposition to Modifier.onSizeChanged, Modifier.layout, or hoisted constraint reads at the parent level. - Tuning Justified SubcomposeLayout: Configures SubcomposeLayoutState with SubcomposeSlotReusePolicy and precompose APIs when measure-time composition is genuinely required. - Use Case: A developer reports scroll jank after wrapping LazyColumn items in BoxWithConstraints; this Skill hoists the constraint read to the list root and verifies the fix with a Perfetto trace. ## Quick Start Ask the assistant to review a Compose screen that uses BoxWithConstraints or nested Scaffold and remove the extra measure passes causing slow first frame or scroll jank.

Frequently Asked Questions about avoiding-subcomposition-pitfalls

High-intent search queries and answers about installing and using this skill.

FAQPage Schema
Why does BoxWithConstraints cause extra measure passes in Compose?▼

BoxWithConstraints is built on SubcomposeLayout, which composes its content during the measure phase rather than the parent's composition pass. Every new Constraints value, such as rotation or IME changes, re-runs that subcomposition.

How do I replace BoxWithConstraints when I only need the size?▼

Use Modifier.onSizeChanged to receive the measured size in the layout phase, or Modifier.layout for custom measurement. Both avoid spinning up a subcomposition just to read maxWidth or maxHeight.

Can I put BoxWithConstraints inside a LazyColumn item?▼

No. Each item subcomposes during the lazy list's measure pass, causing scroll jank. Hoist a single BoxWithConstraints to the list root and pass the resolved value down as a stable parameter.

When should I keep SubcomposeLayout instead of replacing it?▼

Keep it when child composition genuinely depends on measured values like parent constraints or sibling sizes, such as tab strips or anchor-aligned popovers. Tune it with SubcomposeSlotReusePolicy and precompose instead of removing it.

Is nesting Scaffold inside another Scaffold a performance problem?▼

Yes. Each Scaffold is a SubcomposeLayout with its own measure-phase composition, so nesting multiplies that cost on every constraint change. Use the topBar, bottomBar, snackbarHost, and FAB slots of a single Scaffold instead.

How do I verify subcomposition fixes in Compose?▼

Record a Perfetto system trace with androidx.compose.runtime:runtime-tracing and confirm Compose:recompose and Compose:applyChanges no longer fire on every measurement. Layout Inspector recomposition counts should stay flat across constraint changes.