optimizing-lazy-layouts

Fixes scroll jank and lost item state in Jetpack Compose lazy layouts using keys, contentType, and animateItem.

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

SYSTEM DOCUMENTATION & REQUIREMENTS

What problem does it solve? LazyColumn, LazyRow, and lazy grids in Jetpack Compose suffer from scroll jank, dropped frames, lost item state on insert/remove/reorder, and silently broken animateItem() animations when items lack stable keys, contentType discriminators, or stable composable parameters. ## Core Features & Use Cases - Stable item keys: Audits every items() call and enforces server-side stable IDs instead of index-based, random UUID, or hashCode keys. - contentType for mixed feeds: Adds type discriminators so heterogeneous feeds (cards, headers, ads) reuse cached compositions like RecyclerView view-types. - animateItem() validation: Ensures Modifier.animateItem() is paired with stable keys so insert/remove animations actually run. - Allocation hoisting: Moves painters, borders, and shapes out of the items lambda to reduce per-item allocation at scroll velocity. - Use Case: A mixed feed of cards, headers, and ads stutters while scrolling; apply key = { it.id }, contentType = { it::class }, and Modifier.animateItem() to each row, then verify with Layout Inspector recomposition counts. ## Quick Start Ask the assistant to fix the scroll jank and lost item state in your LazyColumn by adding stable keys, contentType, and animateItem to the items block.

Frequently Asked Questions about optimizing-lazy-layouts

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

FAQPage Schema
How do I fix LazyColumn scroll jank in Jetpack Compose?▼

Add a stable key to every items() call using a server-side ID, supply contentType for mixed-type lists, and hoist painters and borders out of the items lambda. Then verify with Layout Inspector that item recomposition counts plateau during scrolling.

Why is Modifier.animateItem() not animating in my LazyColumn?▼

animateItem() binds animation state to the item's key, so without a stable key the animation silently no-ops. Add key = { it.id } to the items() call so inserts, removals, and reorders trigger the fade and placement animations.

What is the contentType parameter in LazyColumn items?▼

contentType is a type discriminator analogous to RecyclerView view-types that lets lazy layouts reuse cached compositions across items of the same type. For mixed feeds of cards, headers, and ads, pass contentType = { it::class } so rows crossing type boundaries are recycled instead of rebuilt.

Can I use the list index or UUID as a LazyColumn item key?▼

No. Index-based keys break state preservation and animations on insert or remove, and UUID.randomUUID() evaluated per emission discards the cached composition every recomposition. Use a stable server-side ID that outlives a single composition.

When should I tune the lazy layout prefetch window instead of keys?▼

Prefetch tuning applies when the bottleneck is heavy items or high-velocity scrolling needing a wider ahead/behind window, not missing keys or contentType. Fix item-level identity and stability first, then use the sibling configuring-lazy-prefetch skill for prefetch adjustments.