Based on NowInAndroid performance patterns.
- MUST use
key()inLazyColumn/LazyRowitems - MUST pass stable types to Composables (primitives,
@Immutable,@Stable) - MUST use
derivedStateOffor values computed from frequently-changing state - MUST use
graphicsLayerfor animated alpha/scale/rotation (avoids relayout) - MUST NOT allocate objects inside Composable without
remember - MUST NOT nest
LazyColumninsideverticalScrollColumn
- MUST use Coil
AsyncImagewith placeholder and error drawables - MUST specify size constraints to prevent OOM
- MUST NOT load full-resolution images for thumbnails
// NIA DynamicAsyncImage pattern
DynamicAsyncImage(
imageUrl = headerImageUrl,
contentDescription = null,
modifier = Modifier.fillMaxWidth(),
)- SHOULD use OkHttp cache for GET responses
- SHOULD set appropriate timeouts (connect: 10s, read: 30s)
- MUST use
@Streamingfor large file downloads
- MUST use
@Transactionfor multi-table operations - MUST run database operations on
Dispatchers.IO - MUST index frequently-queried columns
- SHOULD use
PagingSourcefor large datasets
- MUST defer non-critical initialization after first frame
- NIA uses
trace()wrappers for startup performance tracking - SHOULD use App Startup library for lazy component initialization
// NIA pattern: trace wrapper for performance monitoring
@Provides
@Singleton
fun okHttpCallFactory(): Call.Factory = trace("NiaOkHttpClient") {
OkHttpClient.Builder().build()
}- MUST use convention plugins to avoid Gradle config duplication
- MUST use
implementationoverapito reduce recompilation - MUST use KSP instead of KAPT
- SHOULD enable Gradle parallel build and configuration cache
- NIA generates Baseline Profiles via
:benchmarksmodule - SHOULD include critical user journeys in baseline profile generation
- Reduces JIT compilation on first app launch
Skill: /compose-performance