mobile-best-practices 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/README.md +64 -0
  2. package/assets/data/anti-patterns.csv +114 -0
  3. package/assets/data/architectures.csv +50 -0
  4. package/assets/data/code-snippets.csv +80 -0
  5. package/assets/data/gradle-deps.csv +79 -0
  6. package/assets/data/libraries.csv +102 -0
  7. package/assets/data/performance.csv +229 -0
  8. package/assets/data/platforms/android.csv +247 -0
  9. package/assets/data/platforms/flutter.csv +55 -0
  10. package/assets/data/platforms/ios.csv +61 -0
  11. package/assets/data/platforms/react-native.csv +56 -0
  12. package/assets/data/project-templates.csv +19 -0
  13. package/assets/data/reasoning-rules.csv +57 -0
  14. package/assets/data/security.csv +438 -0
  15. package/assets/data/testing.csv +74 -0
  16. package/assets/data/ui-patterns.csv +92 -0
  17. package/assets/references/CHECKLIST.md +49 -0
  18. package/assets/references/CODE-RULES.md +123 -0
  19. package/assets/scripts/__pycache__/core.cpython-314.pyc +0 -0
  20. package/assets/scripts/core.py +432 -0
  21. package/assets/scripts/search.py +104 -0
  22. package/assets/skills/all.md +245 -0
  23. package/assets/skills/android.md +168 -0
  24. package/assets/skills/flutter.md +153 -0
  25. package/assets/skills/ios.md +149 -0
  26. package/assets/skills/react-native.md +154 -0
  27. package/assets/templates/base/quick-reference.md +41 -0
  28. package/assets/templates/base/skill-content.md +60 -0
  29. package/assets/templates/platforms/agent.json +11 -0
  30. package/assets/templates/platforms/antigravity.json +13 -0
  31. package/assets/templates/platforms/claude.json +27 -0
  32. package/assets/templates/platforms/codebuddy.json +11 -0
  33. package/assets/templates/platforms/codex.json +11 -0
  34. package/assets/templates/platforms/continue.json +11 -0
  35. package/assets/templates/platforms/copilot.json +11 -0
  36. package/assets/templates/platforms/cursor.json +11 -0
  37. package/assets/templates/platforms/gemini.json +11 -0
  38. package/assets/templates/platforms/kiro.json +11 -0
  39. package/assets/templates/platforms/opencode.json +11 -0
  40. package/assets/templates/platforms/qoder.json +11 -0
  41. package/assets/templates/platforms/roocode.json +11 -0
  42. package/assets/templates/platforms/trae.json +11 -0
  43. package/assets/templates/platforms/windsurf.json +11 -0
  44. package/dist/commands/init.d.ts +6 -0
  45. package/dist/commands/init.d.ts.map +1 -0
  46. package/dist/commands/init.js +94 -0
  47. package/dist/commands/init.js.map +1 -0
  48. package/dist/commands/update.d.ts +2 -0
  49. package/dist/commands/update.d.ts.map +1 -0
  50. package/dist/commands/update.js +28 -0
  51. package/dist/commands/update.js.map +1 -0
  52. package/dist/commands/versions.d.ts +2 -0
  53. package/dist/commands/versions.d.ts.map +1 -0
  54. package/dist/commands/versions.js +30 -0
  55. package/dist/commands/versions.js.map +1 -0
  56. package/dist/index.d.ts +3 -0
  57. package/dist/index.d.ts.map +1 -0
  58. package/dist/index.js +27 -0
  59. package/dist/index.js.map +1 -0
  60. package/dist/types/index.d.ts +23 -0
  61. package/dist/types/index.d.ts.map +1 -0
  62. package/dist/types/index.js +24 -0
  63. package/dist/types/index.js.map +1 -0
  64. package/dist/utils/index.d.ts +9 -0
  65. package/dist/utils/index.d.ts.map +1 -0
  66. package/dist/utils/index.js +103 -0
  67. package/dist/utils/index.js.map +1 -0
  68. package/package.json +57 -0
@@ -0,0 +1,229 @@
1
+ Category,Issue,Platform,Severity,Keywords,Description,Do,Dont,Code Good,Code Bad,Metric,Reference URL
2
+ Startup,Cold Start Time,All,Critical,"cold start launch time splash app",App takes too long to launch,Minimize work in Application/AppDelegate/main,Heavy initialization on startup,Lazy-init dependencies use background init,Init all libraries in onCreate/didFinishLaunching,< 1s cold start,https://developer.android.com/topic/performance/vitals/launch-time
3
+ Startup,Splash Screen,Android,Medium,"splash screen core splashscreen api",Splash screen shown too long or flickering,Use Core SplashScreen API with proper theme,Custom splash Activity or fixed delay,installSplashScreen() with keep condition,Thread.sleep(2000) in splash activity,< 500ms splash,https://developer.android.com/develop/ui/views/launch/splash-screen
4
+ Startup,Baseline Profiles,Android,High,"baseline profile startup dex compilation aot",No baseline profiles for AOT compilation,Generate and include baseline profiles,Skip baseline profiles for release,Use Macrobenchmark to generate profiles,No profileinstaller dependency,20-40% faster startup,https://developer.android.com/topic/performance/baselineprofiles/overview
5
+ Startup,Pre-warming Views,iOS,Medium,"prewarm view controller initialization prepare",Key views not pre-initialized,Pre-warm frequently used ViewControllers,Initialize everything lazily on critical path,Prepare next screen data in background,Load everything on viewDidAppear,Faster transitions,https://developer.apple.com/documentation/uikit/view_controllers
6
+ Startup,Tree Shaking,Flutter,Medium,"tree shaking unused code dead import",Unused code included in release build,Enable tree shaking remove unused imports,Import entire packages for one function,import package:lib/specific.dart,import package:lib/lib.dart // entire lib,Smaller binary,https://docs.flutter.dev/perf/app-size
7
+ Startup,Hermes Engine,React Native,High,"hermes engine javascript bytecode startup",Not using Hermes JavaScript engine,Enable Hermes for faster startup,Use JSC engine,hermesEnabled: true in build.gradle,hermesEnabled: false,50% faster startup,https://reactnative.dev/docs/hermes
8
+ Rendering,Compose Recomposition,Android,High,"recomposition compose skip stable remember",Excessive recomposition in Jetpack Compose,Use stable types remember derivedStateOf,Pass unstable lambdas to composables,val callback = remember { { doWork() } },onClick = { viewModel.doWork() } // recreated,< 16ms per frame,https://developer.android.com/develop/ui/compose/performance
9
+ Rendering,SwiftUI Body Complexity,iOS,Medium,"swiftui body complexity view performance extract",Complex view body causing slow rendering,Keep view body simple extract subviews,Giant view body with many conditionals,Extract into smaller focused views,Single View with 200+ lines body,60fps,https://developer.apple.com/documentation/swiftui/view/body-swift.property
10
+ Rendering,Widget Rebuild,Flutter,High,"widget rebuild build method performance const",Unnecessary widget tree rebuilds,Use const widgets and targeted rebuilds,Rebuild entire tree on any state change,const Text('Static') and BlocBuilder,setState in parent rebuilds all children,< 16ms build,https://docs.flutter.dev/perf/best-practices
11
+ Rendering,FlatList Optimization,React Native,High,"flatlist performance render virtualization getitemlayout",FlatList rendering slowly,Use getItemLayout removeClippedSubviews,Render all items without virtualization,getItemLayout for fixed-size items,No keyExtractor inline renderItem,60fps scroll,https://reactnative.dev/docs/optimizing-flatlist-configuration
12
+ Rendering,Overdraw,Android,Medium,"overdraw gpu rendering layers background",Multiple overlapping background draws,Remove unnecessary backgrounds,Stack multiple backgrounds on same area,Single background on container only,Background on parent AND child,< 2x overdraw,https://developer.android.com/topic/performance/rendering/overdraw
13
+ Rendering,Offscreen Rendering,iOS,High,"offscreen rendering shadow cornerradius mask layer",Shadows and corners causing offscreen passes,Use shadowPath and rasterize for shadows,cornerRadius + shadow without shadowPath,layer.shadowPath = UIBezierPath().cgPath,layer.cornerRadius + layer.shadow,Avoid offscreen passes,https://developer.apple.com/documentation/quartzcore/calayer
14
+ Rendering,Skia Shader Jank,Flutter,Medium,"shader compilation jank first frame stutter sksl",Shader compilation causing first-run jank,Warm up shaders with SkSL capture,Ignore first-run jank,flutter run --cache-sksl,No shader warmup,Eliminate first-run jank,https://docs.flutter.dev/perf/shader
15
+ Memory,Leak Detection,Android,Critical,"memory leak leakcanary hprof profiler",Memory leaks going undetected,Use LeakCanary in debug builds,Ship without leak detection,debugImplementation leakcanary-android,No leak detection tools,0 leaked activities,https://square.github.io/leakcanary/
16
+ Memory,Image Memory,All,High,"image memory bitmap large resize decode",Loading full-size images into memory,Resize images to view dimensions,Load 4000x3000 for 200x200 view,Coil/Glide auto-resize to ImageView size,BitmapFactory.decodeFile(path) full size,< 100MB app memory,https://developer.android.com/topic/performance/graphics
17
+ Memory,ViewHolder Recycling,Android,Medium,"recyclerview viewholder recycle bind lazy",Not properly recycling views in lists,Use RecyclerView or LazyColumn with keys,Create new views for every item,LazyColumn(items key = { it.id }),Column { items.forEach { ItemView(it) } },Constant memory in lists,https://developer.android.com/develop/ui/views/layout/recyclerview
18
+ Memory,ARC Retain Cycles,iOS,Critical,"arc retain cycle weak strong closure delegate",Strong reference cycles in closures,Use weak/unowned references in closures,Strong self capture in closures,{ [weak self] in self?.doWork() },{ self.doWork() } // strong capture,No retain cycles,https://docs.swift.org/swift-book/documentation/the-swift-programming-language/automaticreferencecounting/
19
+ Memory,Isolate Memory,Flutter,Medium,"isolate memory compute heavy background json",Heavy computation on main isolate,Use compute() or Isolate.spawn,JSON parsing on main isolate,final result = await compute(parseJson data),final result = jsonDecode(bigString),Main < 60ms work,https://dart.dev/language/concurrency
20
+ Memory,Bridge Overhead,React Native,High,"bridge overhead serialization js native turbo",Excessive JS-Native bridge calls,Batch bridge calls minimize serialization,Many small messages across bridge,Use Turbo Modules / JSI,Frequent bridge calls in scroll handler,< 10ms bridge,https://reactnative.dev/docs/the-new-architecture/landing-page
21
+ Network,Request Deduplication,All,Medium,"deduplicate request cache api concurrent",Making duplicate API requests,Cache and deduplicate identical requests,Fire same request from multiple components,Repository with in-flight request cache,Each screen independently calls same API,1 request per unique query,
22
+ Network,Image Size,All,High,"image size cdn resize thumbnail bandwidth",Loading oversized images from server,Request images sized for device density,Load 2000px image for 100dp view,CDN image resizing: url?w=200&q=80,Always load full-resolution,Match image to view,
23
+ Network,Gzip Compression,All,Medium,"gzip compression response size bandwidth brotli",Not using response compression,Enable gzip/brotli for API responses,Uncompressed JSON responses,Accept-Encoding: gzip on client,No compression header,60-80% smaller responses,
24
+ Network,Connection Pooling,All,Medium,"connection pool http reuse keep-alive client",Creating new HTTP connections per request,Reuse HTTP client instance with pool,New OkHttpClient per request,Single OkHttpClient instance via DI,val client = OkHttpClient() per call,Reuse connections,https://square.github.io/okhttp/features/connections/
25
+ Network,Prefetching Data,All,Medium,"prefetch preload data anticipate next screen",Not prefetching likely-needed data,Prefetch next screen data on behavior,Load data only on navigate,Prefetch detail when list item visible,Fetch on screen appear only,Faster perceived load,
26
+ Battery,Location Updates,All,High,"location gps battery drain frequency accuracy",High-frequency location updates,Use appropriate accuracy and distance filter,GPS updates every second,Significant location changes or 100m filter,requestLocationUpdates(0 0f) continuous,Minimize GPS time,https://developer.android.com/develop/sensors-and-location/location
27
+ Battery,Background Work,All,High,"background work battery schedule constraint optimization",Uncontrolled background work,Use WorkManager/BGTaskScheduler with constraints,Continuous background polling,WorkManager with network constraint,AlarmManager every 5 minutes,Respect battery optimization,https://developer.android.com/develop/background-work/background-tasks
28
+ Battery,Wake Locks,Android,Critical,"wakelock cpu screen battery drain timeout",Holding wake locks unnecessarily,Release wake locks ASAP use timeout,Hold wake lock entire operation,wakeLock.acquire(10*60*1000L) timeout,wakeLock.acquire() no timeout,Always set timeout,https://developer.android.com/training/scheduling/wakelock
29
+ Battery,Sensor Usage,All,Medium,"sensor accelerometer gyroscope battery active",Keeping sensors active when not needed,Unregister sensors when not in use,Keep accelerometer on in background,Unregister in onPause/viewDidDisappear,Never unregister listeners,Register only when visible,https://developer.android.com/develop/sensors-and-location/sensors/sensors_overview
30
+ List,Stable Keys,All,High,"key stable identifier list recomposition diff",Using index as key for list items,Use unique stable ID from data model,Use list index or random key,key = { item.id },key = { index } unstable on reorder,Correct diff calculation,https://developer.android.com/develop/ui/compose/lists#item-keys
31
+ List,Item Recycling,All,High,"recycle view lazy list virtualized flatlist",Not using virtualized lists,Use LazyColumn/List/ListView.builder/FlatList,Render all items in ScrollView,LazyColumn { items(data) { Item(it) } },Column { data.forEach { Item(it) } },O(visible) not O(total),https://developer.android.com/develop/ui/compose/lists
32
+ List,Avoid Nested Scroll,All,Medium,"nested scroll recyclerview scrollview conflict",Nested scrollable containers,Use single scrollable with item types,RecyclerView inside ScrollView,Single LazyColumn with item types,ScrollView containing LazyColumn,Single scroll context,https://developer.android.com/develop/ui/compose/lists
33
+ List,Preload Items,All,Medium,"preload prefetch list ahead buffer smooth",Not preloading items ahead,Configure prefetch distance,Only render visible with no buffer,prefetchItemCount = 10,No prefetch configuration,Seamless scrolling,
34
+ List,Diffing Algorithm,All,Medium,"diffutil diffing list update async diff",Not using efficient list diffing,Use DiffUtil/automatic diffing,Reload entire list on change,submitList(newList) DiffUtil handles,adapter.notifyDataSetChanged(),Update only changed items,https://developer.android.com/reference/androidx/recyclerview/widget/DiffUtil
35
+ Image,Lazy Image Loading,All,High,"lazy image load visible viewport demand",Loading all images regardless of visibility,Load images only when entering viewport,Load all images on screen creation,LazyColumn with AsyncImage per item,Load all images in onStart,Load on demand only,
36
+ Image,Image Placeholder,All,Medium,"placeholder image loading skeleton fade crossfade",No placeholder while image loads,Show placeholder with crossfade transition,Show empty space per image,AsyncImage with placeholder crossfade,Image(url) no placeholder,Smooth loading,
37
+ Image,Image Format,All,Medium,"webp avif format compression quality size",Using unoptimized image formats,Use WebP/AVIF for smaller files,Serve PNG for photos,Use WebP format from CDN,Original PNG/BMP format,30-50% smaller than JPEG,https://developer.android.com/topic/performance/reduce-apk-size#use-webp
38
+ Image,Image Downsampling,All,High,"downsample resize decode memory bitmap target",Decoding full-resolution images,Downsample to target view size,Decode full image then scale,inSampleSize matching view,BitmapFactory.decodeFile full res,Match decoded to view,https://developer.android.com/topic/performance/graphics/load-bitmap
39
+ Animation,Main Thread Animation,All,High,"animation main thread ui jank 60fps frame",Animation calculations blocking main thread,Use dedicated animation frameworks,Calculate animation on main thread,Platform animation APIs Reanimated,Manual frame in setTimeout,60fps animation,
40
+ Animation,Lottie Performance,All,Medium,"lottie animation json heavy complex size",Heavy Lottie animations impacting performance,Limit complexity use hardware acceleration,Lottie for every micro-interaction,Lottie for complex branded only,Lottie for simple fade/slide,< 5MB animation files,https://github.com/airbnb/lottie-android
41
+ Bundle,APK Size,Android,Medium,"apk size bundle abi split shrink minify",Large APK size affecting downloads,Enable minification ABI splits resource shrinking,Ship universal APK all ABIs,R8 fullMode per-ABI APK,Single universal no minification,< 15MB per ABI,https://developer.android.com/topic/performance/reduce-apk-size
42
+ Bundle,Deferred Components,Flutter,Medium,"deferred components split download size lazy",Large initial download size,Use deferred components for later features,Bundle everything in initial download,DeferredComponent for rare features,All features in single binary,Smaller initial install,https://docs.flutter.dev/perf/deferred-components
43
+ Bundle,Code Push,React Native,Medium,"codepush ota update bundle js over-the-air",Full app store release for minor fixes,Use CodePush for JS bundle OTA updates,Full release for text change,CodePush for JS-only changes,Full release for copy changes,Faster iteration,https://learn.microsoft.com/en-us/appcenter/distribution/codepush/
44
+ Bundle,ProGuard R8 Rules,Android,High,"proguard r8 rules shrink obfuscate keep",Missing or incorrect ProGuard rules,Configure proper keep rules test release,Skip ProGuard or keep everything,Specific keep rules for models,-keep class ** { *; },Smaller obfuscated APK,https://developer.android.com/build/shrink-code
45
+ Compose,Remember Calculations,Android,High,"compose remember expensive calculation recomposition cache",Expensive calculations running on every recomposition,Use remember to cache calculation results,Recalculate on every recomposition,"val sorted = remember(contacts, comparator) { contacts.sortedWith(comparator) }","items(contacts.sortedWith(comparator)) // sorts on every recomposition",< 16ms per frame,https://developer.android.com/develop/ui/compose/performance/bestpractices
46
+ Compose,Lazy Layout Keys,Android,High,"lazycolumn lazyrow keys stable recomposition item",Items recompose unnecessarily when list order changes,Provide stable unique keys for lazy layout items,Use index or no key for items,"items(notes, key = { it.id }) { NoteRow(it) }","items(notes) { NoteRow(it) } // no key causes full recomposition",Minimal recomposition,https://developer.android.com/develop/ui/compose/performance/bestpractices
47
+ Compose,DerivedStateOf Recomposition,Android,High,"derivedstateof state recomposition limit reduce",State changes too frequently causing excessive recomposition,Use derivedStateOf for computed state,Read state directly causing constant recomposition,"val showButton by remember { derivedStateOf { listState.firstVisibleItemIndex > 0 } }","val showButton = listState.firstVisibleItemIndex > 0 // recomposes on every scroll pixel",< 16ms per frame,https://developer.android.com/develop/ui/compose/performance/bestpractices
48
+ Compose,Defer State Reads,Android,Medium,"compose defer lambda state read scope recomposition",Reading state high in tree causes wide recomposition scope,Pass state as lambda to defer read to usage site,Read state immediately in parent scope,"Title(snack) { scroll.value } // lambda defers read","Title(snack, scroll.value) // parent recomposes on scroll",Narrow recomposition,https://developer.android.com/develop/ui/compose/performance/bestpractices
49
+ Compose,Backwards Writes,Android,Critical,"backwards write infinite loop recomposition state",Writing to state after reading causes infinite recomposition,Only write state in event handlers never after reading,Write to state after reading in composition,"Button(onClick = { count++ }) { Text() } // write in event","var count by remember { mutableStateOf(0) }; Text(\"$count\"); count++ // backwards write",No infinite loops,https://developer.android.com/develop/ui/compose/performance/bestpractices
50
+ Startup,Baseline Profiles,Android,High,"baseline profile startup optimization speed jit aot",Slow app startup and navigation without ahead-of-time compilation,Use Baseline Profiles to precompile critical code paths,Rely only on JIT compilation for all code,"generateBaselineProfile { } // in build.gradle","// No Baseline Profile - 30% slower first launch",< 1s cold start,https://developer.android.com/topic/performance/baselineprofiles/overview
51
+ Startup,Startup Profiles,Android,High,"startup profile dex layout optimization cold start",Suboptimal DEX layout causing slower app startup,Use startup profiles for compile-time DEX layout optimization,Default DEX layout without optimization,"android { experimentalProperties['android.experimental.art-profile-r8-rewriting'] = true }","// No startup profile - slower class loading",< 1s cold start,https://developer.android.com/topic/performance/baselineprofiles/dex-layout-optimizations
52
+ Startup,App Startup Library,Android,High,"app startup library initializer contentprovider dependency",Multiple ContentProviders slowing down app initialization,Use App Startup library with single shared ContentProvider,Create separate ContentProvider for each library,"class WorkManagerInitializer : Initializer<WorkManager> { override fun dependencies() = listOf<Class<out Initializer<*>>>() }","<provider android:name='WorkManagerProvider' /> <provider android:name='OtherProvider' /> // multiple providers",Faster startup,https://developer.android.com/topic/libraries/app-startup
53
+ Startup,Lazy Library Loading,Android,Medium,"lazy loading defer initialization on-demand workmanager",Libraries auto-initializing on startup increasing launch time,Defer non-critical library initialization until after first frame,Auto-initialize all libraries on app startup,"WorkManager.initialize(context, config) // called after first frame","// WorkManager auto-inits on startup via ContentProvider",First frame < 1s,https://developer.android.com/topic/performance/appstartup/best-practices
54
+ Startup,ViewStub Lazy Inflation,Android,Medium,"viewstub lazy inflate defer layout view hierarchy",Inflating entire view hierarchy on startup slowing first frame,Use ViewStub to defer inflating non-critical views,Inflate all views upfront in onCreate,"<ViewStub android:id='@+id/stub' android:layout='@layout/complex_view' />; stub.inflate() // when needed","<include layout='@layout/complex_view' /> // inflated immediately",Faster first frame,https://developer.android.com/topic/performance/appstartup/best-practices
55
+ Startup,Splash Screen Optimization,Android,Medium,"splash screen android 12 splashscreen api startup",Custom splash screen implementation causing delays,Use Android 12+ SplashScreen API with proper theming,Custom splash activity or manual splash implementation,"<style><item name='android:windowSplashScreenBackground'>@color/splash</item></style>","startActivity(Intent(this, SplashActivity::class.java)) // extra activity",< 1s cold start,https://developer.android.com/about/versions/12/features/splash-screen
56
+ Image,Image Format Optimization,Android,Medium,"webp vector drawable image size startup performance",Large PNG/JPG images increasing app size and startup time,Use vector drawables and WebP format for smaller file sizes,Use PNG or JPG for all images,"<vector android:width='24dp'>...</vector>; image.webp file","large_icon.png (500KB) instead of icon.webp (50KB)",< 15MB APK,https://developer.android.com/topic/performance/appstartup/best-practices
57
+ Startup,Cold Start Tracing,Android,High,"cold start trace profiling measure startup performance",Not measuring cold start performance accurately,Use system tracing to profile and optimize cold starts,Only measure warm/hot starts or no measurement,"adb shell am start -W -n com.app/.MainActivity; Trace.beginSection('coldStart')","// No tracing - can't identify startup bottlenecks",< 1s cold start,https://developer.android.com/topic/performance/vitals/launch-time
58
+ Security,Android Keystore,Android,Critical,"keystore hardware cryptographic keys secure storage","Storing cryptographic keys in code or SharedPreferences",Use Android Keystore for hardware-backed key storage,Store keys in app code or plain SharedPreferences,"KeyGenParameterSpec.Builder('myKey', PURPOSE_ENCRYPT | PURPOSE_DECRYPT).setUserAuthenticationRequired(true).build()","val key = 'hardcoded_key_123' // insecure hardcoded key",Keys protected,https://developer.android.com/privacy-and-security/keystore
59
+ Security,Biometric Authentication,Android,High,"biometric fingerprint face authentication strong weak","Using only PIN/password without biometric option",Implement BIOMETRIC_STRONG for sensitive operations,No biometric auth or using deprecated FingerprintManager,"BiometricPrompt(activity, executor, callback).authenticate(PromptInfo.Builder().setAllowedAuthenticators(BIOMETRIC_STRONG).build())","// Only password auth - no biometric option",Secure auth,https://developer.android.com/training/sign-in/biometric-auth
60
+ Security,Certificate Pinning,Android,Critical,"certificate pinning ssl mitm network security config","Trusting all SSL certificates vulnerable to MITM attacks",Pin certificates in network security config,Accept all certificates or no pinning,"<network-security-config><domain-config><domain includeSubdomains='true'>api.example.com</domain><pin-set><pin digest='SHA-256'>base64hash=</pin></pin-set></domain-config></network-security-config>","// TrustAllCerts - accepts any certificate including fake ones",Prevent MITM,https://developer.android.com/privacy-and-security/security-config
61
+ Security,Cleartext Traffic,Android,High,"cleartext http https network security insecure","Allowing HTTP connections exposing data in transit",Block cleartext traffic enforce HTTPS only,Allow HTTP traffic for production APIs,"<network-security-config><base-config cleartextTrafficPermitted='false' /></network-security-config>","android:usesCleartextTraffic='true' // allows HTTP traffic",All HTTPS,https://developer.android.com/privacy-and-security/risks/cleartext-communications
62
+ Security,Code Obfuscation,Android,Medium,"proguard r8 obfuscation reverse engineering decompile","Unobfuscated code easy to reverse engineer",Enable R8/ProGuard obfuscation shrinking,Ship release builds without obfuscation,"buildTypes { release { minifyEnabled true; shrinkResources true; proguardFiles getDefaultProguardFile('proguard-android-optimize.txt') } }","minifyEnabled false // code easily decompiled",Harder to reverse,https://developer.android.com/build/shrink-code
63
+ Security,Root Detection,Android,Medium,"root detection rooted device security bypass","App runs on rooted devices bypassing security",Detect and restrict functionality on rooted devices,No root detection allowing security bypass,"if (RootBeer(context).isRooted) { showSecurityWarning(); disableSensitiveFeatures() }","// No root check - sensitive features work on rooted devices",Limit exposure,https://developer.android.com/privacy-and-security/risks
64
+ Security,Play Integrity API,Android,High,"play integrity api app verification tamper detection","Not verifying app integrity allowing modified APKs",Use Play Integrity API to detect app tampering,No integrity checks allowing repackaged apps,"IntegrityManagerFactory.create(context).requestIntegrityToken(IntegrityTokenRequest.builder().setCloudProjectNumber(projectId).build())","// No integrity check - modified APKs can access backend",Genuine apps only,https://developer.android.com/google/play/integrity
65
+ Security,Encrypted SharedPreferences,Android,High,"encrypted sharedpreferences androidx security crypto","Storing sensitive data in plain SharedPreferences",Use EncryptedSharedPreferences for sensitive data,Store tokens passwords in plain SharedPreferences,"EncryptedSharedPreferences.create(context, 'secure_prefs', masterKey, AES256_SIV, AES256_GCM)","sharedPrefs.edit().putString('auth_token', token) // stored in plaintext",Data encrypted,https://developer.android.com/topic/security/data
66
+ Security,WebView JavaScript Safety,Android,High,"webview javascript setjavascriptenabled addjavascriptinterface","Enabling JavaScript without proper security controls",Disable JavaScript unless required; use @JavascriptInterface with trusted content only,"Enable JavaScript for all content or expose sensitive methods via addJavascriptInterface","webView.settings.javaScriptEnabled = false; // Or: class JsBridge { @JavascriptInterface fun secureMethod() { } }; webView.addJavascriptInterface(JsBridge(), 'bridge')","webView.settings.javaScriptEnabled = true; webView.addJavascriptInterface(SensitiveAPI(), 'api') // exposes all public methods",XSS prevented,https://developer.android.com/privacy-and-security/risks/webview-unsafe-file-inclusion
67
+ Security,Secure Logging,Android,Critical,"logging buildconfig debug r8 strip sensitive data","Logging sensitive data in production builds","Use BuildConfig.DEBUG conditional logging; strip logs with R8; never log PII tokens passwords","Log sensitive data unconditionally in production",if (BuildConfig.DEBUG) { Log.d(TAG 'Debug info') }; // R8 proguard-rules: -assumenosideeffects class android.util.Log { public static *** d(...); },"Log.d(TAG, 'User password: $password') // Always logged including production",No PII leaks,https://developer.android.com/privacy-and-security/risks/log-info-disclosure
68
+ Security,SQL Injection Prevention,Android,Critical,"sql injection room parameterized query rawQuery","Using string concatenation for SQL queries","Use Room with @Query or SQLite parameterized queries with ?","Concatenate user input directly into SQL strings","@Query('SELECT * FROM users WHERE id = :userId') fun getUser(userId: String); // Or: db.query('users', null, 'id = ?', arrayOf(userId), null)","db.rawQuery('SELECT * FROM users WHERE name = $userInput') // SQL injection vulnerable",Query safe,https://developer.android.com/training/data-storage/room/accessing-data
69
+ Security,Input Validation,Android,High,"input validation sanitize regex whitelist","Accepting untrusted input without validation","Validate and sanitize all inputs with regex whitelisting length checks","Trust all user input without validation","val email = input.takeIf { it.matches(Regex('[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}')) } ?: throw IllegalArgumentException('Invalid email')","val userId = intent.getStringExtra('user_id'); deleteUser(userId) // No validation - injection risk",Inputs validated,https://developer.android.com/privacy-and-security/security-tips#input-validation
70
+ Security,Hardcoded Credentials,Android,Critical,"hardcoded credentials api key password secret buildconfig","API keys passwords secrets hardcoded in source code","Use Android Keystore BuildConfig secrets-gradle-plugin; never commit secrets to git","Hardcode API keys passwords in source code or BuildConfig","// secrets.properties (gitignored): API_KEY=xyz; // build.gradle.kts: secrets { propertiesFileName = 'secrets.properties' }; // Access: BuildConfig.API_KEY; // Or: KeyStore for runtime secrets","const val API_KEY = 'sk_live_1234567890abcdef'; // EXPOSED in decompiled APK; // Or: buildConfigField 'String' 'API_KEY' '\"secret\"' // Committed to git",Secrets leaked,https://developer.android.com/privacy-and-security/security-tips
71
+ Security,Third-Party SDK Risks,Android,High,"third party sdk supply chain dependency vulnerability","Untrusted or outdated third-party libraries introducing vulnerabilities","Vet all SDKs; use dependency scanning; keep libraries updated; read SDK privacy policies","Use outdated or unverified third-party libraries without security review","// build.gradle.kts: dependencies { implementation('com.trusted:library:2.1.0') // Latest verified version }; // Scan: ./gradlew dependencyCheckAnalyze; // Review SDK data collection in Data Safety section","dependencies { implementation('com.unknown:sdk:1.0.0') } // Outdated malicious unknown; // No dependency scanning or privacy review",Supply chain attack,https://developer.android.com/privacy-and-security/risks
72
+ Security,Insecure App Signing,Android,Critical,"app signing keystore jks release security","Weak keystore management or exposed signing keys","Use strong keystore passwords; store in CI environment variables; never commit keystores","Commit keystore to git; use weak passwords; share keystore files","// CI environment variables: KEYSTORE_PASSWORD KEYSTORE_KEY_PASSWORD; signingConfigs { release { storeFile = file(System.getenv('KEYSTORE_PATH')); storePassword = System.getenv('KEYSTORE_PASSWORD') } }",".gitignore without *.jks; // keystore.jks committed to repository; // password='android123' in gradle.properties also committed",Keys compromised,https://developer.android.com/studio/publish/app-signing
73
+ Security,Debug Code in Production,Android,High,"debug code production release leak deobfuscate logging","Debug features left enabled in production builds","Remove all debug code with BuildConfig.DEBUG checks; strip logs with R8; disable debugging","Ship production APK with debug features enabled or debuggable=true","if (BuildConfig.DEBUG) { enableDebugMenu(); Log.d(TAG 'Debug info') }; // AndroidManifest.xml: android:debuggable='false'; // R8 strips debug code in release","<application android:debuggable='true'> // NEVER in production; enableDebugMenu(); // Always enabled exposing admin features; Log.d() without BuildConfig check",App debuggable,https://developer.android.com/studio/debug
74
+ Security,Excessive Data Collection,Android,High,"excessive data collection privacy gdpr ccpa google play","Collecting unnecessary user data violating privacy policies","Collect only essential data; declare in Data Safety; follow GDPR/CCPA; minimize permissions","Collect all available data without user consent or disclosure","// Minimal collection: val essentialData = UserData(userId username); // Data Safety declaration in Play Console; requestPermissions(ESSENTIAL_PERMISSIONS)","// Collect everything: deviceId contacts location callLogs sms; // No Data Safety declaration; // No privacy policy; // Violates Play Store policies",Policy violation,https://developer.android.com/privacy-and-security/privacy-controls
75
+ Startup,16KB Page Size Compatibility,Android,Critical,16kb page size ndk native library tlb arm memory,Apps with native libraries crash or perform poorly on 16KB page-size devices (Android 15+ ARM),Recompile all NDK and native libraries with 16KB page alignment; test on 16KB emulator; required by Play Store Nov 2025,Ship native code compiled for 4KB pages only; ignore 16KB requirement,android { defaultConfig { ndk { abiFilters 'arm64-v8a' } }; // recompiled with -Wl -z max-page-size=16384 },Native .so compiled with 4KB page alignment; crashes on 16KB devices; Play Console rejection,20-30% faster startup,https://developer.android.com/guide/practices/page-sizes
76
+ Startup,Macrobenchmark Startup Testing,Android,High,macrobenchmark benchmark startup test measure cold warm hot,Not measuring startup performance with real benchmarks leads to undetected regressions,Use Macrobenchmark library to measure cold/warm/hot start; integrate into CI; compare compilationModes,Manual timing or no measurement; skip benchmarking in CI,@Test fun startup() = benchmarkRule.measureRepeated(packageName startupMode = COLD) { pressHome(); startActivityAndWait() },// No startup benchmark; manual stopwatch timing; no CI integration,< 1s TTID,https://developer.android.com/topic/performance/benchmarking/macrobenchmark-overview
77
+ Startup,TTID vs TTFD Optimization,Android,High,ttid ttfd time initial display full display reportfully drawn,Only optimizing Time to Initial Display while Full Display takes much longer,Optimize both TTID and TTFD; call reportFullyDrawn() after content ready; measure in Macrobenchmark,Focus only on first frame; ignore time until app is actually usable,reportFullyDrawn() // called after data loaded and UI rendered; Macrobenchmark measures both TTID and TTFD,// No reportFullyDrawn(); TTID fast but data loads 3s later; no TTFD measurement,TTFD < 2s,https://developer.android.com/topic/performance/vitals/launch-time
78
+ Rendering,Compose Strong Skipping Mode,Android,High,compose strong skipping mode compiler recomposition unstable skip,Composables with unstable parameters recompose unnecessarily without strong skipping,Enable Strong Skipping Mode in Compose compiler 1.5.4+; reduces unnecessary recompositions automatically,Manually wrap every lambda in remember; mark every class @Stable,composeCompiler { enableStrongSkippingMode = true } // gradle,// Manual: val cb = remember { { doWork() } }; @Stable data class everywhere,< 16ms frames,https://developer.android.com/develop/ui/compose/performance/stability
79
+ Rendering,Compose Compiler Metrics,Android,Medium,compose compiler metrics reports stability restartable skippable,Not monitoring Compose stability causes hidden performance issues,Generate compiler reports to identify unstable classes; fix stability issues,Ship without checking compose compiler metrics,./gradlew assembleRelease -PenableComposeCompilerMetrics=true -PenableComposeCompilerReports=true,// Never check compiler reports; unstable classes cause full recompositions,All key composables skippable,https://developer.android.com/develop/ui/compose/performance/stability/diagnose
80
+ Bundle,R8 Full Mode Optimization,Android,High,r8 full mode shrink optimize obfuscate startup size agp,R8 full mode disabled losing 40% startup improvement and 14% size reduction,Enable R8 full mode (default AGP 8.0+); test reflection; add keep rules as needed,Disable R8 full mode with android.enableR8.fullMode=false; skip proguard testing,// gradle.properties: remove android.enableR8.fullMode=false; // test thoroughly with release build,android.enableR8.fullMode=false // disables deep optimizations; 40% slower startup,40% faster cold start,https://developer.android.com/build/shrink-code
81
+ Rendering,JankStats Frame Monitoring,Android,Medium,jankstats jank frame drop monitor production metrics,Frame drops going undetected in production; no real-world jank data,Use JankStats library to monitor frame timing in production; report drops to analytics,Only check jank in development; no production monitoring,val jankStats = JankStats.createAndTrack(window) { frame -> if (frame.isJank) report(frame) },// No production frame monitoring; jank only visible in profiler during development,< 1% janky frames,https://developer.android.com/topic/performance/jankstats
82
+ Rendering,ANR Prevention,Android,Critical,anr application not responding main thread block 5s broadcast,App shows ANR dialog when main thread blocked > 5s or BroadcastReceiver > 10s,Move all I/O database network to background; use coroutines with Dispatchers.IO; monitor ANR rate,Perform disk I/O network or heavy computation on main thread,withContext(Dispatchers.IO) { database.query() }; // never block main thread,runBlocking { api.fetch() } // blocks main thread; ANR after 5 seconds,< 0.47% ANR rate,https://developer.android.com/topic/performance/vitals/anr
83
+ Startup,KSP over KAPT Migration,Android,Medium,ksp kapt annotation processing kotlin symbol build speed,KAPT slows builds by 25-40% with stub generation step,Migrate annotation processors to KSP; Hilt Room Moshi all support KSP; 2x faster builds,Continue using KAPT when KSP alternative exists,ksp 'com.google.dagger:hilt-compiler:2.51'; ksp 'androidx.room:room-compiler:2.6.1',kapt 'com.google.dagger:hilt-compiler:2.51' // generates Java stubs; 2x slower,2x faster annotation processing,https://developer.android.com/build/migrate-to-ksp
84
+ Rendering,StrictMode Performance Detection,Android,Medium,strictmode disk network main thread policy detection debug,Disk reads and network calls on main thread going undetected during development,Enable StrictMode in debug builds to detect main thread violations early,Ship debug without StrictMode; find violations in production,if (BuildConfig.DEBUG) StrictMode.setThreadPolicy(ThreadPolicy.Builder().detectAll().penaltyLog().build()),// No StrictMode; disk reads on main thread cause subtle jank,0 StrictMode violations,https://developer.android.com/reference/android/os/StrictMode
85
+ Rendering,Perfetto System Tracing,Android,Medium,perfetto trace system profiling custom section method,Using basic logging instead of structured tracing for performance analysis,Use Perfetto with custom trace sections for precise performance analysis,println-based timing or no tracing,trace('loadData') { repository.fetchItems() }; // visible in Perfetto UI,println('Start:' + System.currentTimeMillis()) // no structured tracing,Identify bottlenecks,https://developer.android.com/studio/profile/perfetto-overview
86
+ Bundle,App Bundle Dynamic Delivery,Android,High,app bundle aab dynamic delivery feature module on demand,Shipping fat APKs instead of optimized App Bundles; wasting 15-20% size,Use Android App Bundle with dynamic feature modules; reduces APK size per device by 15-20%,Ship universal APK or single monolithic APK for all devices,// build.gradle: bundle { language { enableSplit true }; density { enableSplit true }; abi { enableSplit true } },// Single universal APK: 80MB with all densities ABIs languages included,15-20% smaller per device,https://developer.android.com/guide/app-bundle
87
+ Memory,Kotlin Coroutines Dispatcher Selection,Android,High,coroutines dispatcher io default main unconfined thread pool,Using wrong dispatcher causing thread pool exhaustion or main thread blocking,Use Dispatchers.IO for I/O; Default for CPU; Main for UI; inject dispatchers for testing,Use Dispatchers.IO for CPU work or Main for I/O; hardcode dispatchers,withContext(dispatchers.io) { api.call() }; withContext(dispatchers.default) { parseJson(data) },GlobalScope.launch(Dispatchers.Main) { database.query() } // blocks UI; leaks,Correct thread usage,https://developer.android.com/kotlin/coroutines/coroutines-best-practices
88
+ Memory,DataStore over SharedPreferences,Android,Medium,datastore proto sharedpreferences preferences async coroutine,SharedPreferences blocking main thread with synchronous I/O and no type safety,Use Jetpack DataStore for async type-safe preferences; Proto DataStore for complex data,Use SharedPreferences with commit() on main thread; putString for complex objects,val TOKEN by dataStore.data.map { it[TOKEN_KEY] }.collectAsState(); // async non-blocking,sharedPrefs.edit().putString('data' json).commit() // synchronous; blocks main thread,Non-blocking reads,https://developer.android.com/topic/libraries/architecture/datastore
89
+ Rendering,Compose Navigation Performance,Android,Medium,navigation compose destination backstack animation transition,Navigation Compose creating new instances on every navigation causing re-initialization,Use SavedStateHandle; configure proper NavHost animations; avoid heavy composables at route level,Re-create complex composables on every navigation; no saved state,NavHost(startDestination = route) { composable(route) { viewModel: VM = hiltViewModel() } },// No SavedStateHandle; heavy init in composable(); full reload on back navigation,Instant back navigation,https://developer.android.com/guide/navigation/design/compose
90
+ Rendering,Adaptive Layout Multi-Window,Android,Medium,adaptive layout foldable large screen multi-window tablet,App crashes or performs poorly in multi-window and foldable configurations,Use WindowSizeClass for adaptive layouts; test on foldable emulators; handle configuration changes,Hardcode portrait layout; ignore multi-window; recreate activity on fold,val windowSizeClass = calculateWindowSizeClass(this); when(windowSizeClass.widthSizeClass) { Compact -> ... },// Fixed portrait layout; crashes in split-screen; ignores fold state,Smooth multi-window,https://developer.android.com/develop/ui/compose/layouts/adaptive
91
+ Build,Gradle Configuration Cache,Android,High,gradle configuration cache build speed incremental compile,Gradle re-evaluating build scripts on every build wasting time,Enable configuration cache for 25%+ faster incremental builds,Rebuild configuration from scratch every time,// gradle.properties: org.gradle.configuration-cache=true,// No configuration cache; full rebuild of task graph every compilation,25% faster builds,https://docs.gradle.org/current/userguide/configuration_cache.html
92
+ Build,Gradle Build Scans,Android,Medium,gradle build scan analysis bottleneck task slow plugin,Not identifying slow tasks or plugins in build pipeline,Use build scans to identify and fix build bottlenecks; integrate into CI,Guess which tasks are slow; no build analysis,./gradlew assembleDebug --scan // generates detailed build report,// No build analysis; slow builds without knowing root cause,Identify slow tasks,https://scans.gradle.com/
93
+ Build,Multi-Module Build Parallelization,Android,High,module parallel build speed modularize gradle independent,Monolithic module prevents parallel compilation; full rebuild on any change,Modularize app into independent modules; enable parallel builds; use api vs implementation correctly,Single app module with everything; all code recompiles on any change,// gradle.properties: org.gradle.parallel=true; // feature modules with implementation deps only,// Single :app module; 500+ files recompile on any change; 5min build times,Parallel module builds,https://developer.android.com/topic/modularization
94
+ Rendering,90fps+ High Refresh Rate,Android,Medium,90fps 120fps refresh rate display frame budget rendering,Targeting only 60fps on 90/120Hz displays causing visible stutter,Detect and target device refresh rate; adjust animation frame budget accordingly,Hardcode 60fps assumptions; ignore high refresh rate displays,Surface.setFrameRate(90f FRAME_RATE_COMPATIBILITY_DEFAULT); // request 90fps,// Hardcoded 16ms frame budget; stutters on 90Hz (11ms budget) and 120Hz (8ms budget) displays,Match display refresh,https://developer.android.com/media/optimize/performance/frame-rate
95
+ Startup,iOS Instruments Time Profiler,iOS,High,instruments time profiler cpu trace bottleneck xcode performance,Not profiling app startup and runtime CPU usage with Instruments,Use Time Profiler in Instruments to identify CPU bottlenecks; profile on real device,Guess at performance issues; only profile on simulator,Product > Profile > Time Profiler; analyze heaviest stack trace; optimize top callers,// No profiling; assume performance is fine; ship without measurement,Identify hot paths,https://developer.apple.com/documentation/xcode/improving-your-app-s-performance
96
+ Startup,iOS MetricKit Performance Monitoring,iOS,High,metrickit mxmetricmanager diagnostics launch hang cpu disk,No production performance monitoring; issues only found through user complaints,Use MetricKit MXMetricManager to collect launch time CPU hangs disk I/O metrics in production,Rely only on crash reports; no performance telemetry,class AppMetrics: MXMetricManagerSubscriber { func didReceive(_ payloads: [MXMetricPayload]) { analyze(payloads) } },// No MetricKit; performance issues invisible until app store reviews,< 1s launch p95,https://developer.apple.com/documentation/metrickit
97
+ Startup,iOS Xcode Organizer Insights,iOS,Medium,xcode organizer energy disk launch metrics regression trends,Not reviewing Xcode Organizer for real-world performance regressions between releases,Check Organizer > Metrics weekly for launch time energy regressions across app versions,Ignore Xcode Organizer metrics; only look at crash logs,Window > Organizer > Metrics > Launch Time; compare across versions; set performance budgets,// Never check Organizer; regressions go unnoticed for months,Track version trends,https://developer.apple.com/documentation/xcode/analyzing-your-app-s-performance
98
+ Rendering,SwiftUI LazyVStack Optimization,iOS,High,swiftui lazyvstack lazylist scroll performance cell identity id,Using VStack for long lists causing all views to be created immediately,Use LazyVStack/LazyHStack with stable identifiers for large scrolling content,VStack with ForEach for 1000+ items; unstable IDs causing full redraws,LazyVStack { ForEach(items id: \.stableId) { item in ItemRow(item) } },VStack { ForEach(items) { item in ItemRow(item) } } // all 1000 items created at once,60fps scroll,https://developer.apple.com/documentation/swiftui/lazyvstack
99
+ Rendering,iOS Core Animation Layer Optimization,iOS,High,core animation calayer shadow cornerradius rasterize shouldrasterize offscreen,Shadows and corner radius together forcing expensive offscreen rendering passes,Set shadowPath explicitly; use shouldRasterize for static layers; separate shadow and corner views,cornerRadius + shadow without shadowPath; triggering offscreen render pass every frame,layer.shadowPath = UIBezierPath(roundedRect: bounds cornerRadius: 12).cgPath; layer.shouldRasterize = true,layer.cornerRadius = 12; layer.shadowOffset = CGSize(width: 0 height: 2) // offscreen render every frame,0 offscreen passes,https://developer.apple.com/documentation/quartzcore/calayer
100
+ Memory,Swift Structured Concurrency Performance,iOS,High,swift async await task taskgroup structured concurrency actor,Using GCD dispatch queues for concurrent work instead of modern structured concurrency,Use async/await Task TaskGroup and actors for safe concurrent code; automatic cancellation,Use DispatchQueue.global().async with manual completion handlers; risk of data races,func fetchAll() async throws { async let a = api.fetchA(); async let b = api.fetchB(); return try await (a b) },DispatchQueue.global().async { let result = try? api.fetch(); DispatchQueue.main.async { self.update(result) } },Fewer data races,https://developer.apple.com/documentation/swift/concurrency
101
+ Memory,iOS Combine Publisher Performance,iOS,Medium,combine publisher subscriber operator chain overhead memory,Long Combine chains with multiple operators creating unnecessary allocations and overhead,Keep Combine chains short; use share() for multicasted publishers; cancel subscriptions properly,Chain 10+ operators; no subscription management; multiple subscribers to expensive publisher,let shared = publisher.share(); sub1 = shared.sink { ... }; sub2 = shared.sink { ... },publisher.map{}.filter{}.map{}.debounce{}.map{}.flatMap{} // 10+ operators; expensive re-subscription,Efficient pipelines,https://developer.apple.com/documentation/combine
102
+ Rendering,iOS UICollectionView Compositional Layout,iOS,High,uicollectionview compositional layout diffable datasource prefetch,Custom layout subclasses performing poorly with complex calculations,Use UICollectionViewCompositionalLayout with DiffableDataSource for efficient complex layouts,Custom UICollectionViewLayout with manual calculations; reloadData on changes,var layout = UICollectionViewCompositionalLayout { section env in ... }; dataSource.apply(snapshot),collectionView.reloadData() // full reload; custom layout calculateLayoutAttributes O(n^2),Efficient layout,https://developer.apple.com/documentation/uikit/uicollectionviewcompositionallayout
103
+ Rendering,iOS Metal GPU Optimization,iOS,Medium,metal gpu compute shader graphics rendering pipeline acceleration,Not leveraging Metal for GPU-accelerated image processing and rendering,Use Metal for heavy image processing CIFilter compute; offload from CPU to GPU,Process large images on CPU; use Core Graphics for real-time filters,let commandBuffer = commandQueue.makeCommandBuffer(); let blitEncoder = commandBuffer.makeBlitCommandEncoder(),UIGraphicsBeginImageContext for real-time 4K image filter processing // CPU bound,GPU-accelerated,https://developer.apple.com/documentation/metal
104
+ Startup,iOS dyld Launch Closure Optimization,iOS,Medium,dyld launch closure dynamic linking framework startup load,Too many dynamic frameworks slowing app launch due to dyld loading overhead,Merge small frameworks; use static linking where possible; minimize dynamic framework count,50+ dynamic frameworks each adding 10-20ms to launch; no framework consolidation,// Static linking: prefer .a over .framework for internal libs; merge small frameworks,// 60 dynamic frameworks: 60 * 15ms = ~900ms just in dyld loading,< 20 dynamic libs,https://developer.apple.com/documentation/xcode/improving-app-launch-time
105
+ Rendering,iOS os_signpost Performance Intervals,iOS,Medium,os_signpost signpost pointsofinterest interval measure custom trace,Using print timestamps instead of structured performance measurement,Use os_signpost to create custom Instruments intervals; visible in Points of Interest,NSLog-based timing; no Instruments integration,let log = OSLog(subsystem: 'com.app' category: .pointsOfInterest); os_signpost(.begin log: log name: 'DataLoad'),print('Start: \(Date())') // not visible in Instruments; manual calculation,Visual profiling,https://developer.apple.com/documentation/os/logging/recording_performance_data
106
+ Memory,iOS Xcode Memory Graph Debugger,iOS,Medium,memory graph debugger xcode leak cycle reference retain allocation,Memory leaks detected too late; retain cycles invisible without tooling,Use Xcode Memory Graph Debugger to visualize retain cycles and leaked objects,Rely only on dealloc logs; miss subtle retain cycles,Debug > Debug Memory Graph; analyze purple leak icons; fix retain cycles,// No memory graph analysis; retain cycles grow memory until OOM crash,0 leaked objects,https://developer.apple.com/documentation/xcode/gathering-information-about-memory-use
107
+ Network,iOS Background URLSession,iOS,Medium,background urlsession download upload transfer discretionary resume,App killed during large downloads; transfers not resuming,Use background URLSession for large transfers; enable isDiscretionary for non-urgent,Default URLSession for 100MB+ downloads; killed when app suspends,let config = URLSessionConfiguration.background(withIdentifier: 'download'); config.isDiscretionary = true,URLSession.shared.dataTask(with: url) // killed when app suspends; download lost,Reliable transfers,https://developer.apple.com/documentation/foundation/urlsessionconfiguration/1407496-background
108
+ Battery,iOS Background Tasks Framework,iOS,Medium,bgtaskscheduler bgprocessingtask bgapprefreshtask background maintenance,Using background fetch API incorrectly wasting battery,Use BGTaskScheduler with processing and refresh tasks; set constraints,Continuous background polling; no system scheduling,BGTaskScheduler.shared.register(forTaskWithIdentifier: id queue: nil) { task in process(task as! BGProcessingTask) },Timer.scheduledTimer(withTimeInterval: 60) { _ in fetchData() } // runs constantly; drains battery,Respect battery,https://developer.apple.com/documentation/backgroundtasks
109
+ Bundle,iOS App Thinning and Bitcode,iOS,Medium,app thinning bitcode slicing on demand resources asset catalog odr,Shipping universal binary with all assets increasing download size,Use App Thinning with asset catalogs; on-demand resources for large assets,Include all asset variants in single download; 500MB app,// Asset Catalog with device-specific variants; On-Demand Resources for level data,// All 3x 2x 1x assets included; all game levels bundled; 500MB download,50%+ smaller,https://developer.apple.com/documentation/xcode/reducing-your-app-s-size
110
+ Rendering,Flutter Impeller Renderer,Flutter,High,impeller renderer skia gpu shader jank compilation first frame,Skia shader compilation causing first-frame jank on iOS and Android,Enable Impeller renderer for pre-compiled shaders; eliminates shader jank entirely,Use Skia with manual SkSL warmup; first-frame stutter on new screens,// flutter run --enable-impeller; // or: Info.plist FLTEnableImpeller = YES,// Skia: shader compilation jank on first render of each unique draw call,0 shader jank,https://docs.flutter.dev/perf/impeller
111
+ Rendering,Flutter DevTools Performance Overlay,Flutter,Medium,devtools performance overlay timeline trace rebuild widget,Not using Flutter DevTools to identify rendering and rebuild bottlenecks,Use DevTools Performance tab; enable performance overlay; analyze timeline,Print-based timing; no structured performance analysis,// flutter run --profile; DevTools > Performance > Timeline Events > identify slow frames,// No profiling; guess at performance issues; debug mode performance is misleading,< 16ms frames,https://docs.flutter.dev/tools/devtools/performance
112
+ Rendering,Flutter RepaintBoundary Isolation,Flutter,Medium,repaintboundary repaint isolate child widget rendering boundary,Child widget repaints causing entire subtree to re-render,Wrap frequently updating widgets in RepaintBoundary to isolate paint region,Allow animation widget to trigger repaint of entire parent tree,RepaintBoundary(child: AnimatedWidget()) // isolates repaint to this subtree only,Stack(children: [HeavyBackground() AnimatedOverlay()]) // background repaints on every frame,Isolated repaints,https://api.flutter.dev/flutter/widgets/RepaintBoundary-class.html
113
+ Memory,Flutter Isolate.run for Compute,Flutter,High,isolate compute run heavy json parse image process background thread,Heavy computation on main isolate causing UI freezes; compute() copies data,Use Isolate.run for CPU-intensive work; automatic cleanup; no manual isolate management,Parse large JSON or process images on main isolate; UI freezes during processing,final result = await Isolate.run(() => jsonDecode(bigString)); // background isolate,final result = jsonDecode(bigJsonString); // blocks main isolate; UI frozen,< 16ms main thread,https://dart.dev/language/isolates
114
+ Rendering,Flutter const Constructor Optimization,Flutter,Medium,const constructor widget build compile-time constant immutable rebuild,Widgets without const constructors rebuilding unnecessarily on parent setState,Use const constructors for static widgets; compiler optimizes away rebuilds,Omit const on static widgets; entire subtree rebuilds on any state change,const Text('Hello'); const SizedBox(height: 16); const Icon(Icons.star),Text('Hello'); SizedBox(height: 16); // recreated on every build call,Skip rebuilds,https://docs.flutter.dev/perf/best-practices#use-const-widgets-where-possible
115
+ Image,Flutter Image.network Caching,Flutter,Medium,image network cache cached_network_image placeholder memory disk,Loading network images without caching causing re-downloads and flickering,Use cached_network_image with placeholder; disk and memory caching,Image.network without cache; re-downloads on every rebuild,CachedNetworkImage(imageUrl: url placeholder: (ctx url) => CircularProgressIndicator()),Image.network(url) // no caching; re-downloads on scroll; flickers on rebuild,Cache hit > 90%,https://pub.dev/packages/cached_network_image
116
+ Rendering,Flutter ListView.builder vs Column,Flutter,High,listview builder column children scroll virtualize lazy create,Using Column or ListView with children for large lists; all items created at once,Use ListView.builder for lazy item creation; only visible items created,Column with hundreds of children; or ListView(children: items.map(...).toList()),ListView.builder(itemCount: items.length itemBuilder: (ctx i) => ItemWidget(items[i])),Column(children: items.map((i) => ItemWidget(i)).toList()) // creates all 1000 items,O(visible) items,https://docs.flutter.dev/cookbook/lists/long-lists
117
+ Build,Flutter Release Mode Profiling,Flutter,Medium,release profile mode debug performance measurement accurate timing,Measuring performance in debug mode with assertions and debug checks enabled,Always measure performance in profile or release mode; debug is 10x slower,Performance test in debug mode; false bottleneck identification,flutter run --profile // realistic timing with observatory access,flutter run // debug mode; 10x slower than release; misleading results,Accurate metrics,https://docs.flutter.dev/testing/build-modes
118
+ Rendering,Flutter Platform Channel Overhead,Flutter,Medium,platform channel method event overhead latency serialization native,Excessive platform channel calls between Dart and native causing latency,Batch platform channel calls; use Pigeon for type-safe generated code; minimize round-trips,Multiple small platform channel calls in hot loops; manual serialization,final result = await pigeon.batchOperation(items); // single call,for (item in items) { await channel.invokeMethod('process' item); } // 100 round-trips,< 5ms per call,https://docs.flutter.dev/platform-integration/platform-channels
119
+ Bundle,Flutter Deferred Components,Flutter,Medium,deferred component split download installTime playcore dynamic feature,Large initial download size with all features bundled,Use deferred components to split features for on-demand download,Bundle all features including rarely-used ones in initial install,@pragma('vm:deferred-import') import 'heavy_feature.dart' deferred as heavy; heavy.loadLibrary(),// All features in main binary: 80MB initial download,30% smaller initial,https://docs.flutter.dev/perf/deferred-components
120
+ Startup,Flutter Engine Prewarming,Flutter,Medium,flutter engine prewarm preload startup initialization cache,Flutter engine cold start adding 300-500ms to first screen,Pre-warm Flutter engine in native code before showing Flutter screen,Create FlutterEngine only when Flutter screen needed,// iOS: flutterEngine = FlutterEngine(); flutterEngine.run() // in AppDelegate,// Create engine in viewDidLoad; 500ms delay before Flutter content appears,< 300ms engine,https://docs.flutter.dev/add-to-app/performance
121
+ Memory,Flutter Memory Leak Prevention,Flutter,High,memory leak dispose controller stream subscription timer cancel,Controllers streams timers not disposed causing memory leaks,Always dispose controllers cancel subscriptions and timers in dispose(),Skip dispose; rely on garbage collection; controllers live forever,@override void dispose() { _controller.dispose(); _subscription.cancel(); _timer.cancel(); super.dispose(); },// No dispose() override; StreamController and AnimationController leak memory,0 leaked controllers,https://docs.flutter.dev/testing/common-errors
122
+ List,React Native FlashList,React Native,High,flashlist flash list shopify performance flatlist alternative fast scroll,FlatList rendering slowly with complex items; dropping frames on fast scroll,Use FlashList from Shopify for 5x faster list rendering; estimatedItemSize required,FlatList with complex renderItem; no getItemLayout; slow scroll performance,<FlashList data={items} renderItem={renderItem} estimatedItemSize={80} />,<FlatList data={items} renderItem={({item}) => <ComplexItem item={item} />} /> // slow with 1000+ items,60fps scroll,https://shopify.github.io/flash-list/
123
+ Animation,React Native Reanimated Worklets,React Native,High,reanimated worklet ui thread animation gesture handler shared value,Animations running on JS thread causing dropped frames and jank,Use Reanimated 3 with worklets running on UI thread; shared values for 60fps,Animated API with useNativeDriver:false; JS thread animations,const offset = useSharedValue(0); const style = useAnimatedStyle(() => ({ transform: [{ translateX: offset.value }] })),Animated.timing(animValue { toValue: 1 useNativeDriver: false }).start() // JS thread animation,60fps animation,https://docs.swmansion.com/react-native-reanimated/
124
+ Rendering,React Native New Architecture JSI,React Native,High,new architecture jsi turbo modules fabric synchronous native bridge,Old Bridge serializing all JS-Native communication through JSON adding latency,Enable New Architecture with JSI for synchronous native access; Fabric for concurrent rendering,Old Bridge with async JSON serialization for every native call,// newArchEnabled=true in gradle.properties; TurboModules with direct C++ binding,// Old Bridge: JSON.stringify -> Java -> JSON.parse for every native call; 5-10ms overhead,< 1ms native call,https://reactnative.dev/docs/the-new-architecture/landing-page
125
+ Rendering,React Native InteractionManager,React Native,Medium,interactionmanager deferred task animation complete schedule heavy,Heavy work running during animations causing dropped frames,Defer expensive work until after animations complete using InteractionManager,Run data processing during navigation animation; visible jank,InteractionManager.runAfterInteractions(() => { processData(); loadImages(); }),navigation.navigate('Detail'); processData(); // runs during transition animation; jank,Smooth transitions,https://reactnative.dev/docs/interactionmanager
126
+ Memory,React Native Hermes GC Tuning,React Native,Medium,hermes gc garbage collection memory threshold pause tuning,Hermes garbage collection pauses causing visible UI stutters,Tune Hermes GC thresholds; reduce object allocation in hot paths; avoid large closures,Default GC settings with excessive allocations; visible GC pauses during scroll,// Reduce allocations: reuse objects; avoid creating objects in renderItem; pre-allocate arrays,// new Array(1000).fill(0).map(() => ({ key: Math.random() })) // in renderItem; GC thrash,< 5ms GC pause,https://reactnative.dev/docs/hermes
127
+ Rendering,React Native React.memo Optimization,React Native,Medium,react memo usememo usecallback rerender pure component shallow,Components re-rendering unnecessarily on parent state changes,Use React.memo useMemo useCallback to prevent unnecessary re-renders,No memoization; entire list re-renders on any state change,const Item = React.memo(({item}) => <View>{item.name}</View>); const handler = useCallback(() => {} []),const Item = ({item}) => <View>{item.name}</View>; // re-renders on every parent state change,Minimal re-renders,https://react.dev/reference/react/memo
128
+ Bundle,React Native RAM Bundle,React Native,Medium,ram bundle random access module inline requires lazy loading startup,Loading entire JS bundle on startup increasing Time to Interactive,Use RAM bundle format with inline requires for lazy module loading,Single monolithic bundle loaded entirely on startup,// metro.config.js: serializer: { customSerializer: createModuleIdFactory }; require('HeavyModule') inline,// require('AllModules') at top level; 5MB bundle parsed on startup; 3s TTI,< 2s TTI,https://reactnative.dev/docs/ram-bundles-inline-requires
129
+ Rendering,React Native Image Performance,React Native,Medium,image performance fast-image cache priority preload resize,Default Image component re-downloading without caching; slow loading,Use react-native-fast-image with priority caching resize,Default Image component; no caching strategy; re-downloads on scroll,<FastImage source={{uri priority: FastImage.priority.high}} resizeMode='cover' />,<Image source={{uri: url}} /> // no caching; re-downloads; no priority control,Cache hit > 95%,https://github.com/DylanVann/react-native-fast-image
130
+ Startup,React Native Lazy Screen Loading,React Native,Medium,lazy screen loading react.lazy suspense navigation stack tab dynamic import,All screens imported eagerly increasing startup bundle parse time,Use React.lazy with Suspense for screen-level code splitting,Import all screens at top level; parsed on startup even if never visited,const Profile = React.lazy(() => import('./screens/Profile')); <Suspense fallback={<Loading/>}><Profile/></Suspense>,import Profile from './screens/Profile'; // parsed on startup; 500ms wasted if never visited,< 1s startup,https://react.dev/reference/react/lazy
131
+ Build,React Native Metro Bundle Optimization,React Native,Medium,metro bundler config tree shaking minify source map optimization,Unoptimized Metro bundler config shipping larger bundles than necessary,Configure Metro for tree shaking minification; use RAM bundles for production,Default Metro config; no optimization; debug source maps in production,// metro.config.js: transformer: { minifierPath: 'metro-minify-terser' minifierConfig: { compress: { drop_console: true } } },// Default metro config; console.log in production; no tree shaking; large bundle,30% smaller bundle,https://metrobundler.dev/docs/configuration
132
+ Network,Firebase Performance Monitoring,All,Medium,firebase performance monitoring trace http metric production latency,No production performance monitoring; issues only found through complaints,Use Firebase Performance SDK for automatic HTTP tracing and custom traces,No production monitoring; rely on development profiling only,val trace = Firebase.performance.newTrace('data_load'); trace.start(); ... trace.stop(),// No production monitoring; performance regressions invisible,Track prod metrics,https://firebase.google.com/docs/perf-mon
133
+ Network,Request Timeout Configuration,All,Medium,timeout connect read write network request retry backoff,No timeouts on network requests; app hangs when server unresponsive,Set connect/read/write timeouts; implement retry with exponential backoff,No timeout configuration; infinite wait on slow connections,OkHttpClient.Builder().connectTimeout(10 SECONDS).readTimeout(30 SECONDS).build(),OkHttpClient() // default no timeout; hangs forever on slow connection,< 30s total wait,https://square.github.io/okhttp/features/connections/
134
+ Network,Response Pagination,All,High,pagination infinite scroll cursor offset limit page network bandwidth,Loading all data at once causing slow load times and high memory usage,Implement cursor-based or offset pagination; load 20-50 items per page,Load all 10000 records at once; OOM on large datasets,api.getItems(cursor = lastId limit = 20); // cursor-based pagination,api.getAllItems() // returns 10000 records; 5s load; 200MB memory,< 500ms per page,
135
+ Memory,JSON Parsing Optimization,All,Medium,json parse serialization moshi kotlinx gson swift codable performance,Using reflection-based JSON parsing adding 2-5x overhead,Use code-gen serialization: kotlinx.serialization Moshi codegen Swift Codable,Gson with reflection; manual JSONObject parsing; no code generation,@Serializable data class User(val id: Int val name: String); Json.decodeFromString<User>(json),JSONObject(json).getString('name') // manual parsing; no type safety; 3x slower,2-5x faster parse,https://github.com/Kotlin/kotlinx.serialization
136
+ Memory,Database Query Optimization,All,High,database query index room sqlite core data fetch optimize n+1,Unindexed queries and N+1 problems causing slow data access,Add indexes on queried columns; use JOIN instead of N+1; limit result sets,No indexes; SELECT * queries; N+1 queries in loops,@Query('SELECT * FROM items WHERE category = :cat ORDER BY date DESC LIMIT 20'); // indexed column,@Query('SELECT * FROM items'); // no WHERE; loads all rows; no index on lookup column,< 50ms queries,https://developer.android.com/training/data-storage/room/accessing-data
137
+ Memory,Caching Strategy Implementation,All,High,cache lru disk memory strategy ttl invalidation stale-while-revalidate,No caching strategy causing duplicate network requests and slow UX,Implement multi-layer caching: memory (LRU) + disk + network with TTL,No caching; every screen visit refetches from server,val cache = LruCache<String Result>(maxSize = 50); fun get(key: String) = cache.get(key) ?: fetchAndCache(key),// Every screen load: api.fetchData() // no caching; 500ms wait even for unchanged data,> 80% cache hit,
138
+ Battery,Thermal Throttling Awareness,All,Medium,thermal throttling cpu temperature performance degradation battery heat,App ignoring device thermal state causing user discomfort and CPU throttling,Monitor thermal state; reduce work intensity when device is hot,Ignore thermal warnings; continue heavy processing when device overheating,ProcessInfo.processInfo.thermalState; PowerManager.THERMAL_STATUS; reduce quality on warning,// Continuous max-CPU processing; device burns hot; OS throttles CPU to 50%,Adapt to thermals,https://developer.android.com/reference/android/os/PowerManager#getCurrentThermalStatus()
139
+ Network,Offline-First Architecture,All,High,offline first cache local database sync queue network unavailable,App unusable without network; crashes or shows empty screens offline,Store data locally; queue mutations; sync when online; show cached data immediately,Require network for all features; show error on no connection,val data = localDb.getAll(); launch { syncWithServer(pendingChanges) },if (!isOnline) { showError('No internet') } // unusable offline,Works offline,
140
+ Rendering,Pull-to-Refresh Performance,All,Medium,pull refresh swipe scroll indicator loading debounce throttle,Pull-to-refresh triggering multiple rapid API calls; no debounce,Debounce refresh action; show loading indicator; prevent concurrent refreshes,Allow rapid pull-to-refresh; no debounce; multiple concurrent fetches,var isRefreshing by remember { mutableStateOf(false) }; if (!isRefreshing) { isRefreshing = true; refresh() },// Every pull triggers api.fetch() immediately; 5 rapid pulls = 5 concurrent requests,1 concurrent refresh,
141
+ Memory,Object Pool Pattern,All,Medium,object pool reuse allocation gc garbage collection recycle bitmap,Frequent allocation and deallocation of expensive objects causing GC pressure,Reuse expensive objects via pool pattern; recycle bitmaps and buffers,Create new Bitmap/Buffer for every operation; high GC pressure,val pool = BitmapPool(maxSize = 10); val bitmap = pool.acquire(w h config); pool.release(bitmap),val bitmap = Bitmap.createBitmap(w h config) // every frame; massive GC pressure; 50ms pauses,< 5ms GC pause,
142
+ Network,WebSocket Connection Management,All,Medium,websocket connection keepalive reconnect heartbeat timeout backoff,WebSocket connections dropping silently; no reconnection strategy,Implement heartbeat ping/pong; automatic reconnection with backoff; connection state monitoring,Open WebSocket and assume it stays connected; no health check,val ws = OkHttpClient().newWebSocket(request webSocketListener); // with ping interval and reconnect,WebSocket(url) // no heartbeat; no reconnect; silently dies after 30s idle,99.9% uptime,
143
+ Rendering,Adaptive Refresh Rate,All,Medium,refresh rate display 60fps 90fps 120fps adaptive variable vrr promotion,Rendering at fixed 60fps when display supports 90/120Hz; wasting smoothness potential,Detect and adapt to display refresh rate; use variable refresh rate APIs,Hardcode 60fps frame budget everywhere; ignore display capabilities,view.display?.refreshRate // adapt animation frame budget; requestHighRefreshRate where beneficial,// Assume 16.6ms frame budget everywhere; stutter on 120Hz display expecting 8.3ms,Match display Hz,
144
+ Build,CI Performance Regression Testing,All,High,ci continuous integration performance regression benchmark test baseline,Performance regressions shipping to production without detection,Run benchmarks in CI; compare against baseline; fail build on regression,No automated performance testing; manual spot-checks before release,// CI: run macrobenchmark; compare p50 p90 against baseline; alert on > 10% regression,// No CI benchmarks; performance regression discovered by users weeks later,Catch regressions,https://developer.android.com/topic/performance/benchmarking/macrobenchmark-overview
145
+ Startup,Disk I/O Optimization,All,Medium,disk io read write storage file sequential random buffer,Random disk I/O patterns causing 10x slower reads than sequential,Use buffered I/O; prefer sequential reads; batch writes; use memory-mapped files for large data,Unbuffered random I/O; many small writes; no batching,BufferedReader(FileReader(path) 8192); // buffered sequential read,FileReader(path).read() // unbuffered; char-by-char; 100x slower than buffered,Buffered I/O,
146
+ Build,Version Catalog Dependency Management,All,Medium,version catalog toml dependency management centralized update gradle,Dependency versions scattered across multiple build.gradle files,Use Gradle version catalog (libs.versions.toml) for centralized dependency management,Hardcode versions in each module; inconsistent versions; update nightmare,// libs.versions.toml: [versions] compose = '1.7.0'; [libraries] compose-ui = { module = 'compose.ui' version.ref = 'compose' },// build.gradle: implementation 'androidx.compose.ui:ui:1.5.0' // different version in each module,Single source of truth,https://developer.android.com/build/migrate-to-catalogs
147
+ Build,Gradle JVM Heap Size,Android,High,gradle jvm heap memory xmx xms oom build properties,Gradle running out of memory or GC thrashing during build,Set optimal JVM heap in gradle.properties; use 4-8GB for large projects,Use default 512MB heap; causes frequent GC pauses and OOM,// gradle.properties: org.gradle.jvmargs=-Xmx4g -Xms1g -XX:+UseParallelGC -XX:MaxMetaspaceSize=512m,// Default: no jvmargs set; 512MB heap; OOM on large multi-module builds,4GB+ heap for large projects,https://docs.gradle.org/current/userguide/build_environment.html
148
+ Build,Gradle Daemon Persistent Process,Android,High,gradle daemon persistent jvm process startup speed warm,Cold Gradle JVM startup adding 10-15s to every build,Enable Gradle daemon (default on); keep alive for faster subsequent builds,Disable daemon; cold start JVM on every build invocation,// gradle.properties: org.gradle.daemon=true; org.gradle.daemon.idletimeout=10800000 // 3h,// org.gradle.daemon=false; // Cold JVM start every build: +10-15s,Warm daemon builds,https://docs.gradle.org/current/userguide/gradle_daemon.html
149
+ Build,Gradle Parallel Execution,Android,High,gradle parallel execution multimodule concurrent workers,Modules building sequentially wasting multi-core CPU,Enable parallel execution; set workers to CPU core count,Sequential module builds; wasting CPU cores,// gradle.properties: org.gradle.parallel=true; org.gradle.workers.max=8 // match CPU cores,// Sequential: only 1 module builds at a time; 4x slower on 4-module project,Parallel module builds,https://docs.gradle.org/current/userguide/multi_project_configuration_and_execution.html
150
+ Build,Gradle Build Cache,Android,High,gradle build cache local remote ci reuse tasks artifacts,Recompiling unchanged modules from scratch on every build,Enable local + remote build cache; share cache across CI and developers,No caching; full rebuild every time even with no code changes,"// gradle.properties: org.gradle.caching=true; // settings.gradle.kts: buildCache { local { isEnabled = true }; remote(HttpBuildCache::class) { url = uri(""https://cache.company.com/"") } }",// org.gradle.caching=false; // Every build recompiles everything from scratch; 10min CI builds,80%+ cache hit rate,https://docs.gradle.org/current/userguide/build_cache.html
151
+ Build,KSP Over KAPT Migration,Android,Critical,ksp kapt annotation processor compile speed kotlin symbol,KAPT using slow Java stubs generation; 2x slower than KSP,Migrate all annotation processors to KSP; remove KAPT plugin entirely,Use KAPT for Hilt Room Moshi; generates Java stubs before processing,"// build.gradle.kts: plugins { id(""com.google.devtools.ksp"") }; dependencies { ksp(libs.hilt.compiler); ksp(libs.room.compiler); ksp(libs.moshi.codegen) }","// plugins { id(""kotlin-kapt"") }; kapt(libs.hilt.compiler) // Generates Java stubs; 2x slower compilation",2x faster annotation processing,https://developer.android.com/build/migrate-to-ksp
152
+ Build,Non-Transitive R Classes,Android,High,non transitive r class namespace resource build speed android,Transitive R classes generating massive R.java files in every module,Enable non-transitive R classes to reduce build time and APK size,Allow transitive R classes; regenerates massive R files on every change,// gradle.properties: android.nonTransitiveRClass=true; // Use: import com.example.feature.R // fully qualified,// android.nonTransitiveRClass=false; // R.java in :app contains ALL resources from ALL modules,30-40% faster resource processing,https://developer.android.com/build/optimize-your-build
153
+ Build,Gradle File System Watching,Android,Medium,gradle file system watching filesystem incremental change detection,Gradle scanning entire project filesystem for changes on each build,Enable file system watching for instant change detection,Full filesystem scan on every build invocation,// gradle.properties: org.gradle.vfs.watch=true // enabled by default Gradle 7+,// org.gradle.vfs.watch=false; // Rescans entire project tree every build: +2-5s overhead,Instant change detection,https://docs.gradle.org/current/userguide/file_system_watching.html
154
+ Build,Kotlin Incremental Compilation,Android,High,kotlin incremental compilation jvm precise ic speed compile,Full Kotlin recompilation on every change instead of incremental,Enable precise incremental compilation; only recompile affected files,Full recompilation; changing one file recompiles entire module,// gradle.properties: kotlin.incremental=true; kotlin.incremental.usePreciseJavaTracking=true; kotlin.compiler.preciseCompilationResultsBackup=true,// kotlin.incremental=false; // Changing 1 line recompiles 500 files in module,Recompile only affected files,https://kotlinlang.org/docs/gradle-compilation-and-caches.html
155
+ Build,Kotlin Daemon JVM Args,Android,Medium,kotlin daemon jvm memory heap compilation kotlinc speed,Kotlin compiler daemon running out of memory or slow GC,Set Kotlin daemon JVM args separately from Gradle daemon,Use Gradle JVM args for Kotlin compiler; insufficient memory,// gradle.properties: kotlin.daemon.jvmargs=-Xmx2g -XX:+UseParallelGC; // Separate from Gradle daemon,// No kotlin.daemon.jvmargs; uses Gradle's args; may be insufficient for Kotlin compilation,2GB+ for Kotlin daemon,https://kotlinlang.org/docs/gradle-compilation-and-caches.html
156
+ Build,Avoid Dynamic Dependency Versions,Android,High,dynamic dependency version snapshot changing gradle resolve cache,Dynamic versions (1.+ SNAPSHOT latest) breaking caching and reproducibility,Pin exact dependency versions; use version catalog for single source of truth,Use dynamic versions like 1.+ or SNAPSHOT; breaks cache; flaky builds,// libs.versions.toml: [versions] retrofit = '2.11.0'; // Exact pinned version,// implementation('com.squareup.retrofit2:retrofit:2.+') // Resolves different version every build; breaks cache,Reproducible builds,https://docs.gradle.org/current/userguide/dynamic_versions.html
157
+ Build,Gradle Optimized Properties Template,Android,Critical,gradle properties template optimized build speed memory cache recommended,Missing or default gradle.properties without any build optimizations,Use comprehensive optimized gradle.properties template for all projects,Default gradle.properties with only trivial settings,// gradle.properties optimized template: org.gradle.jvmargs=-Xmx4g -Xms1g -XX:+UseParallelGC -XX:MaxMetaspaceSize=512m; org.gradle.parallel=true; org.gradle.caching=true; org.gradle.configuration-cache=true; org.gradle.vfs.watch=true; android.nonTransitiveRClass=true; android.useAndroidX=true; kotlin.incremental=true; kotlin.code.style=official; kotlin.daemon.jvmargs=-Xmx2g,// gradle.properties: org.gradle.jvmargs=-Xmx256m; // Everything else default; 5-10x slower builds than optimized,All optimizations enabled,https://developer.android.com/build/optimize-your-build
158
+ Build,Avoid Unnecessary Plugins,Android,Medium,gradle plugin apply buildscript classpath unused slow configuration,Applying unused plugins in every module slowing configuration phase,Only apply plugins needed per module; use plugins { } DSL with apply false,Apply all plugins in root; apply unused plugins in feature modules,"// root build.gradle.kts: plugins { id(""com.android.library"") version ""8.7.0"" apply false }; // Only apply where needed",// Every module: apply plugin: 'kotlin-kapt'; apply plugin: 'com.google.gms.google-services' // Even when not needed,Faster configuration,https://docs.gradle.org/current/userguide/plugins.html
159
+ Build,Modularize for Incremental Builds,Android,Critical,modularize module incremental build compile isolation api implementation,Single :app module recompiling everything on any source change,Split into feature modules; use implementation over api for dependency isolation,Single monolithic module; changing one file triggers full recompilation,// :core:data (Room+Retrofit) :core:ui (design system) :feature:home :feature:search; dependencies { implementation(project(':core:data')) },// Single :app module with 500+ files; any change = full 5min rebuild,Module-scoped rebuilds,https://developer.android.com/topic/modularization
160
+ Build,Gradle Task Avoidance API,Android,Medium,gradle task avoidance api register create lazy configuration,Eager task creation slowing configuration phase for every build,Use tasks.register (lazy) instead of tasks.create (eager),Use tasks.create which instantiates task even when not needed,"// build.gradle.kts: tasks.register<Copy>(""copyDocs"") { from(""docs""); into(""build/docs"") } // Lazy: only created when executed","// tasks.create(""copyDocs"", Copy::class) { from(""docs"") into(""build/docs"") } // Eager: always configured even if not run",Lazy task creation,https://docs.gradle.org/current/userguide/task_configuration_avoidance.html
161
+ Build,AGP Build Features Toggle,Android,High,agp build features buildconfig viewbinding compose aidl renderscript disable unused,Unused AGP build features generating code on every build,Disable unused build features per module to speed up builds,Leave all build features enabled by default; generates unnecessary code,// build.gradle.kts: android { buildFeatures { viewBinding = false; dataBinding = false; aidl = false; renderScript = false; buildConfig = false } } // Enable only what you need per module,// All features enabled by default; generates BuildConfig ViewBinding stubs etc in every module,Faster per-module builds,https://developer.android.com/reference/tools/gradle-api/current/com/android/build/api/dsl/BuildFeatures
162
+ Build,Gradle Remote Build Cache for CI,Android,High,gradle remote build cache ci cd shared team http push pull,CI builds not sharing cache; rebuilding everything on every pipeline run,Set up remote HTTP build cache; CI pushes; developers pull shared cache,Each CI agent and developer rebuilds from scratch independently,"// settings.gradle.kts: buildCache { remote(HttpBuildCache::class) { url = uri(""https://cache.example.com/cache/""); isPush = System.getenv(""CI"") != null; credentials { username = ""ci""; password = System.getenv(""CACHE_PASSWORD"") } } }",// No remote cache; every CI run does full clean build from scratch; 15min pipelines,Shared cache across CI/devs,https://docs.gradle.org/current/userguide/build_cache.html#sec:build_cache_configure_remote
163
+ Build,Convention Plugins for Multi-Module,Android,High,convention plugin build logic shared dsl multi module gradle,Duplicated build logic across modules; inconsistent configurations,Create convention plugins in buildSrc or build-logic for shared build config,Copy-paste build config in every module's build.gradle.kts,"// build-logic/convention/src/AndroidLibraryConventionPlugin.kt: class AndroidLibraryConventionPlugin : Plugin<Project> { override fun apply(target: Project) { with(target) { pluginManager.apply(""com.android.library""); configure<LibraryExtension> { compileSdk = 35; defaultConfig.minSdk = 26 } } } }",// Every feature module: android { compileSdk = 35; defaultConfig { minSdk = 26 }; compileOptions { ... } } // Same 50 lines copy-pasted in 20 modules,DRY build logic,https://developer.android.com/build/migrate-to-catalogs
164
+ Build,Dependency Locking for Reproducibility,Android,Medium,dependency locking lock file reproducible build gradle version resolve,Transitive dependency versions changing between builds causing inconsistencies,Enable dependency locking for reproducible builds across environments,No locking; transitive dependencies resolve to different versions on different machines,// build.gradle.kts: dependencyLocking { lockAllConfigurations() }; // Generate: ./gradlew dependencies --write-locks,// No locking; transitive dep 'okio' resolves to 3.5.0 locally but 3.6.0 on CI breaking build,Reproducible dependency resolution,https://docs.gradle.org/current/userguide/dependency_locking.html
165
+ Build,Gradle JVM Toolchain,Android,Medium,gradle jvm toolchain java version project compilejava kotlin,Inconsistent Java versions across developer machines and CI,Configure JVM toolchain in Gradle; ensures consistent Java version everywhere,Rely on system JAVA_HOME; different versions on different machines,// build.gradle.kts: kotlin { jvmToolchain(17) }; // Or: java { toolchain { languageVersion.set(JavaLanguageVersion.of(17)) } },// No toolchain; developer A uses Java 11; developer B uses Java 21; CI uses Java 17; build breaks randomly,Consistent JVM version,https://docs.gradle.org/current/userguide/toolchains.html
166
+ Build,Compose Compiler Gradle Plugin,Android,High,compose compiler gradle plugin kotlin version decoupled 2.0,Compose compiler version tightly coupled to Kotlin version; upgrade friction,Use Compose Compiler Gradle plugin (Kotlin 2.0+); decouples Compose from Kotlin version,Use old kotlinCompilerExtensionVersion; must find matching Kotlin+Compose version pairs,"// build.gradle.kts: plugins { id(""org.jetbrains.kotlin.plugin.compose"") version ""2.1.0"" }; // No more kotlinCompilerExtensionVersion needed","// composeOptions { kotlinCompilerExtensionVersion = ""1.5.14"" } // Must match exact Kotlin version; upgrade friction",Decoupled Kotlin+Compose upgrades,https://developer.android.com/develop/ui/compose/compiler
167
+ Database,Room Database Indexing,Android,High,room index query speed sqlite column search where,Slow Room queries on large datasets without proper indexes,Add @ColumnInfo index on frequently queried columns; use compound indexes,No indexes on WHERE/JOIN columns; full table scans on every query,"@Entity(indices = [Index(value = [""email""] unique = true) Index(""createdAt"")]); data class User(@PrimaryKey val id: String @ColumnInfo(index = true) val email: String)",@Entity data class User(@PrimaryKey val id: String val email: String) // No index; full table scan on findByEmail,< 10ms query time,https://developer.android.com/training/data-storage/room/defining-data#column-indexing
168
+ Database,Room WAL Mode,Android,High,room wal write ahead log concurrent read write performance sqlite,Default journal mode blocking reads during writes,Enable WAL mode for concurrent reads and writes; 10x better write performance,Default rollback journal; readers block writers and vice versa,"Room.databaseBuilder(ctx AppDatabase::class.java ""db"").setJournalMode(RoomDatabase.JournalMode.WRITE_AHEAD_LOGGING).build()","Room.databaseBuilder(ctx AppDatabase::class.java ""db"").build() // Default journal mode; reads block during writes",Concurrent read/write,https://developer.android.com/training/data-storage/room
169
+ Database,Batch Database Operations,Android,High,room batch insert upsert transaction bulk write performance,Inserting items one by one in a loop; O(n) transactions,Use @Transaction for batch operations; single transaction for bulk writes,Individual insert/update in a loop; each one creates a separate transaction,@Transaction suspend fun upsertAll(items: List<Entity>) { items.forEach { upsert(it) } } // Single transaction,items.forEach { dao.upsert(it) } // N separate transactions; 100x slower for 1000 items,Single transaction for batch,https://developer.android.com/training/data-storage/room/accessing-data
170
+ Database,Room Paging Integration,Android,Medium,room paging3 pagingsource large dataset lazy load query,Loading entire table into memory for display,Use Room PagingSource for lazy loading large datasets,SELECT * loading 10k+ rows into memory; OOM on large tables,"@Query(""SELECT * FROM items ORDER BY date DESC"") fun pagingSource(): PagingSource<Int Item>","@Query(""SELECT * FROM items"") suspend fun getAll(): List<Item> // Loads 50k rows into memory",Load 20 items at a time,https://developer.android.com/topic/libraries/architecture/paging/v3-paged-data
171
+ Threading,Main Thread Blocking Detection,Android,Critical,main thread blocking anr strictmode disk network ui freeze,Performing disk I/O or network on main thread causing ANR,Use StrictMode in debug to detect main thread violations; move work to IO dispatcher,Ignore ANR warnings; perform blocking work on main thread,StrictMode.setThreadPolicy(StrictMode.ThreadPolicy.Builder().detectAll().penaltyLog().build()),// No StrictMode; database reads on main thread; users see 5s ANR dialog,Zero main thread violations,https://developer.android.com/topic/performance/vitals/anr
172
+ Threading,Coroutine Dispatcher Selection,Android,High,coroutine dispatcher io default main unconfined cpu bound io bound,Using wrong dispatcher for workload type,Use Dispatchers.IO for I/O; Default for CPU; Main for UI only,Use Dispatchers.Main for file reads; IO for sorting algorithms,withContext(Dispatchers.IO) { db.query() }; withContext(Dispatchers.Default) { list.sortBy { it.score } },withContext(Dispatchers.Main) { db.query() } // Blocks UI thread during database query,Correct dispatcher per operation,https://developer.android.com/kotlin/coroutines/coroutines-best-practices
173
+ Threading,Structured Concurrency Leak Prevention,Android,High,structured concurrency viewmodelscope lifecyclescope cancel leak coroutine,Unstructured coroutines leaking beyond lifecycle; memory leaks,Use viewModelScope/lifecycleScope; structured concurrency cancels on destroy,GlobalScope.launch; CoroutineScope without cancel; leaked coroutines,viewModelScope.launch { fetchData() } // Auto-cancelled when ViewModel cleared,GlobalScope.launch { fetchData() } // Never cancelled; leaks memory; runs after screen destroyed,Zero coroutine leaks,https://developer.android.com/kotlin/coroutines/coroutines-best-practices
174
+ Threading,Flow Debounce for Search,Android,Medium,flow debounce search query throttle reduce api calls,Firing API call on every keystroke; 10+ unnecessary requests,Debounce search input with Flow; 300ms delay reduces calls by 90%,API call on every character typed; N calls for N-character search,searchQuery.debounce(300).distinctUntilChanged().flatMapLatest { api.search(it) },searchQuery.collect { api.search(it) } // Fires on every keystroke; 10 API calls for 'hello',300ms debounce,https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/debounce.html
175
+ Compose,Stability and Immutability,Android,High,compose stability immutable stable class recomposition skip annotation,Unstable parameters causing unnecessary recompositions in Compose,Use immutable data classes; annotate with @Stable/@Immutable when needed,Mutable Lists/Maps as Compose parameters; class with var properties,@Immutable data class UiState(val items: ImmutableList<Item> val isLoading: Boolean),data class UiState(val items: List<Item>) // List is unstable; causes recomposition even if content unchanged,All key composables skippable,https://developer.android.com/develop/ui/compose/performance/stability
176
+ Compose,Modifier Chain Ordering,Android,Medium,compose modifier order chain clickable padding clip performance layout,Incorrect modifier ordering causing unexpected behavior and overdraw,Apply modifiers in logical order: clip before background; padding before clickable for touch target,Random modifier ordering; padding after clickable reduces touch target,Modifier.clip(shape).background(color).padding(16.dp).clickable { } // Correct order,Modifier.clickable { }.padding(16.dp) // Touch target smaller than visible area; confusing UX,Correct modifier order,https://developer.android.com/develop/ui/compose/modifiers
177
+ Compose,LazyColumn Content Type,Android,Medium,compose lazycolumn contenttype viewtype heterogeneous list recyclable,Mixed item types in LazyColumn not recycled efficiently,Provide contentType for heterogeneous lists; enables efficient composition recycling,No contentType; Compose cannot reuse compositions across different item types,LazyColumn { items(feed key = { it.id } contentType = { it.type }) { when(it) { is Post -> PostCard(it); is Ad -> AdCard(it) } } },LazyColumn { items(feed) { when(it) { is Post -> PostCard(it); is Ad -> AdCard(it) } } } // No contentType; poor recycling,Efficient composition reuse,https://developer.android.com/develop/ui/compose/lists#content-type
178
+ Compose,movableContentOf for Layout Changes,Android,Medium,compose movable content layout transition preserve state reuse,Composable state lost when moving between layouts (portrait/landscape),Use movableContentOf to preserve state across layout changes,Recreate composable from scratch on layout change; lose scroll position/state,val player = remember { movableContentOf { VideoPlayer(url) } }; if (isFullscreen) FullscreenLayout { player() } else InlineLayout { player() },// On rotation: VideoPlayer recreated; buffering restarts; playback position lost,State preserved across layouts,https://developer.android.com/develop/ui/compose/performance
179
+ Profiling,Android Studio Profiler,Android,High,android studio profiler cpu memory network energy timeline trace,Not using profiler to identify performance bottlenecks,Use Android Studio Profiler for CPU/Memory/Network/Energy analysis,Guess at performance issues without profiling data,View > Tool Windows > Profiler; attach to running process; record CPU trace during janky interaction,// Never profile; assume bottleneck is in wrong place; optimize randomly,Data-driven optimization,https://developer.android.com/studio/profile
180
+ Profiling,Compose Layout Inspector,Android,Medium,compose layout inspector recomposition count debug ui tree semantics,Not tracking recomposition counts in Compose UI,Use Layout Inspector to visualize recomposition counts and identify hot spots,Ship without checking recomposition counts; invisible performance drain,Layout Inspector > Enable 'Show Recomposition Counts'; identify composables recomposing > 1x per frame,// Never check recomposition counts; composables recompose 60x/sec unnecessarily,< 1 recomposition per frame,https://developer.android.com/develop/ui/compose/tooling/layout-inspector
181
+ Profiling,APK Analyzer for Size Optimization,Android,Medium,apk analyzer size dex resources classes method count optimize,Not analyzing APK contents to find size optimization opportunities,Use APK Analyzer to inspect DEX/resources/native libs; find largest contributors,Ship without checking APK size breakdown; bloated resources or duplicate libraries,Build > Analyze APK; sort resources by size; check for duplicate libraries; review DEX method counts,// Never analyze APK; include unused 5MB animation library; duplicate resources across modules,Identify size offenders,https://developer.android.com/tools/apkanalyzer
182
+ Animation,Compose Animation Performance,Android,Medium,compose animation performance animateasstate transition targetbased spec,Animations causing jank by triggering expensive recompositions,Use animateAsState with correct spec; animate in layout/draw phase when possible,Animate by updating state rapidly; causing full recomposition on every frame,val alpha by animateFloatAsState(targetValue = if (visible) 1f else 0f animationSpec = tween(300)),var alpha by remember { mutableStateOf(1f) }; LaunchedEffect(visible) { while(true) { alpha -= 0.01f; delay(16) } } // Manual animation; janky,60fps during animation,https://developer.android.com/develop/ui/compose/animation/introduction
183
+ Animation,Shared Element Transitions,Android,Medium,shared element transition compose navigation predictive back material3,No visual continuity between screens; jarring navigation experience,Use shared element transitions in Navigation Compose for smooth screen transitions,Hard cuts between screens; no visual connection between list and detail,"SharedTransitionLayout { AnimatedContent(screen) { composable -> SharedElement(key = ""image-$id"" animatedContentScope = this) { AsyncImage(url) } } }",// No shared elements; image disappears on list click; reappears on detail screen; jarring UX,Smooth transitions,https://developer.android.com/develop/ui/compose/animation/shared-elements
184
+ Animation,Predictive Back Gesture,Android,Medium,predictive back gesture android 14 15 navigation compose material3,App not supporting predictive back; abrupt back navigation,Implement predictive back for smooth back gesture preview on Android 14+,Override onBackPressed; no back gesture preview,// Enable: AndroidManifest android:enableOnBackInvokedCallback='true'; // Navigation Compose handles automatically with animateContentSize,// Override onBackPressed() in Activity; no gesture preview; abrupt transition on back,Smooth back gesture,https://developer.android.com/guide/navigation/custom-back/predictive-back-gesture
185
+ Accessibility,Content Description Performance,Android,Medium,content description accessibility talkback semantics compose performance,Missing content descriptions causing accessibility failures AND wasted traversal,Provide meaningful contentDescription; use null for decorative images to skip traversal,No contentDescription (fails accessibility); or empty string (TalkBack reads 'unlabeled'),"Icon(Icons.Default.Search contentDescription = ""Search""); Image(painter contentDescription = null) // Decorative: skip","Icon(Icons.Default.Search contentDescription = """") // TalkBack says 'unlabeled'; confusing; or no desc at all",100% labeled interactive elements,https://developer.android.com/develop/ui/compose/accessibility
186
+ Accessibility,Semantics Tree Optimization,Android,Medium,compose semantics tree merging clearandsetsemantics performance talkback,Overly complex semantics tree causing slow TalkBack traversal,Merge semantics for compound components; clearAndSetSemantics for custom descriptions,Every tiny Text and Icon gets its own TalkBack focus; slow navigation,"Modifier.semantics(mergeDescendants = true) { contentDescription = ""Item: $name - $price"" }",// Each Text and Icon separately focusable: TalkBack reads 'name' then 'price' then 'icon' = 3 swipes per item,< 3 swipes per list item,https://developer.android.com/develop/ui/compose/semantics
187
+ Network,GraphQL Query Optimization,All,Medium,graphql query overfetching underfetching fragment persisted batch,REST overfetching returning unused fields; multiple round trips for nested data,Use GraphQL with persisted queries and fragments; fetch exactly what UI needs,REST endpoints returning 50 fields when UI needs 5; N+1 requests for nested data,query GetUser($id: ID!) { user(id: $id) { name avatar posts(first: 10) { title thumbnail } } } // Single request; exact fields,// GET /user/1 -> 50 fields; GET /user/1/posts -> 20 posts with all fields; GET /post/1/comments -> N+1 problem,Zero overfetching,https://graphql.org/learn/best-practices/
188
+ Network,HTTP/2 and Connection Multiplexing,All,Medium,http2 multiplexing connection pool keep alive latency parallel requests,HTTP/1.1 limiting parallel requests to 6 per host; slow cascading loads,Use HTTP/2 for multiplexed streams; single connection handles many requests,HTTP/1.1 with head-of-line blocking; open multiple connections; slow on high latency,// OkHttp uses HTTP/2 by default for HTTPS; Protocol.HTTP_2; single connection multiplexes 100+ requests,// HTTP/1.1: max 6 parallel requests per domain; queue rest; head-of-line blocking,Multiplexed requests,https://square.github.io/okhttp/features/connections/
189
+ Network,API Response Compression,All,Medium,api response compression gzip brotli accept-encoding content-encoding bandwidth,Uncompressed API responses wasting bandwidth; slow on mobile networks,Request compressed responses with Accept-Encoding; enable gzip/brotli on server,Plain JSON responses without compression; 5x larger payloads over network,// OkHttp auto-adds Accept-Encoding: gzip; transparent decompression; 70-80% size reduction,// No compression; 100KB JSON response instead of 20KB; 5x slower on 3G,70%+ compression ratio,https://developer.android.com/training/efficient-downloads/regular-updates
190
+ Battery,Doze Mode and App Standby,Android,High,doze mode app standby battery restrictions idle maintenance window,App not respecting Doze mode; triggering wakelocks in background,Schedule work with WorkManager respecting Doze; use FCM for high-priority messages,AlarmManager.setExact with wakelocks; preventing device sleep,WorkManager.enqueue(request) // Respects Doze; batches work; uses maintenance windows,alarmManager.setExactAndAllowWhileIdle(type triggerAt pendingIntent) // Wakes device constantly,Doze-compatible,https://developer.android.com/training/monitoring-device-state/doze-standby
191
+ Battery,Efficient Network Polling vs Push,All,High,polling push notification fcm websocket sse battery network efficiency,Polling server every 30s for updates; constant network usage draining battery,Use push notifications (FCM/APNs) or WebSocket for real-time; eliminate polling,Poll every 30s even when no new data; wake radio 2880 times/day,// FCM push: server sends notification only when data changes; zero battery when idle,// setInterval(fetchData 30000) // Polls every 30s; 2880 wakeups/day; kills battery,Zero idle network usage,https://developer.android.com/develop/connectivity/network-ops/efficient-network-access
192
+ Accessibility,Touch Target Size,All,High,touch target size 48dp accessibility tap button clickable minimum,Touch targets too small for users with motor impairments,Ensure minimum 48dp touch targets; add padding to small icons,Tiny 24dp buttons with no padding; impossible to tap for many users,Modifier.size(24.dp).clickable { }.padding(12.dp) // Visual 24dp but 48dp touch; // Or: minimumInteractiveComponentSize(),Icon(modifier = Modifier.size(16.dp).clickable { }) // 16dp touch target; impossible for accessibility users,≥ 48dp touch targets,https://developer.android.com/develop/ui/compose/accessibility#touch-target-size
193
+ Accessibility,Color Contrast Ratio,All,High,color contrast ratio wcag accessibility text background readability,Insufficient text-to-background contrast ratio; unreadable for low vision users,Maintain WCAG AA contrast: 4.5:1 for text 3:1 for large text; test with Accessibility Scanner,Light gray text on white background; decorative fonts with low contrast,Text(color = Color(0xFF1A1A1A)) on Surface // 15:1 contrast ratio,Text(color = Color(0xFFBBBBBB)) on Color.White // 1.6:1 ratio; fails WCAG AA; unreadable in sunlight,≥ 4.5:1 contrast,https://developer.android.com/develop/ui/compose/accessibility#color-contrast
194
+ Accessibility,Screen Reader Navigation Order,All,High,screen reader talkback voiceover navigation order focus traversal logical,Illogical screen reader navigation order confusing blind users,Ensure logical reading order matches visual layout; use traversalIndex in Compose,Random focus order; decorative images announced; interactive elements unlabeled,Modifier.semantics { traversalIndex = 1f }; // Control reading order; clearAndSetSemantics for groups,// No traversal control; screen reader jumps randomly between header price button back to title,Logical traversal order,https://developer.android.com/develop/ui/compose/accessibility#traversal-order
195
+ Accessibility,Dynamic Font Scaling,All,High,dynamic font size scaling sp accessibility large text responsive layout,Fixed text sizes ignoring user font preferences; text clipped at large sizes,Use sp units; test at 200% font scale; ensure layouts don't clip or overlap,Hardcoded dp for text; fixed-height containers that clip enlarged text,Text(style = MaterialTheme.typography.bodyLarge) // Uses sp; scales with user preference,Text(fontSize = 14.dp) // dp not sp; ignores accessibility font scaling; or fixed Box(height = 20.dp) { Text(...) } clipping,Readable at 200% scale,https://developer.android.com/develop/ui/compose/designsystems/material3#typography
196
+ Accessibility,Live Region Announcements,Android,Medium,live region accessibility announce polite assertive talkback dynamic content,Dynamic content changes not announced to screen reader users,Use liveRegion for dynamically updated content like errors counters timers,Update text without announcing; screen reader users miss important changes,Modifier.semantics { liveRegion = LiveRegionMode.Polite } // Announces changes to TalkBack,// Error text appears but TalkBack doesn't announce it; user doesn't know login failed,Dynamic updates announced,https://developer.android.com/develop/ui/compose/accessibility#live-region
197
+ Accessibility,Heading Hierarchy,All,Medium,heading hierarchy structure accessibility navigation talkback voiceover,No heading structure; screen reader users can't navigate between sections,Mark headings with semantics { heading() }; create navigable section structure,Flat content with no heading markers; screen reader must read everything linearly,"Text(""Settings"" Modifier.semantics { heading() } style = MaterialTheme.typography.headlineMedium)",// All text same level; no heading markers; TalkBack user must swipe through every item to find sections,Heading navigation works,https://developer.android.com/develop/ui/compose/accessibility
198
+ Accessibility,Custom Action Descriptions,Android,Medium,custom action accessibility long press swipe dismiss semantics action,Complex gestures (long press swipe to dismiss) inaccessible to screen reader users,Add custom accessibility actions for gestures; provide alternatives,Swipe-to-delete with no accessibility alternative; screen reader users can't delete,"Modifier.semantics { customActions = listOf(CustomAccessibilityAction(""Delete"") { deleteItem(id); true }) }",// SwipeToDismiss with no accessibility action; TalkBack users cannot swipe to delete items,All gestures have alternatives,https://developer.android.com/develop/ui/compose/accessibility#custom-actions
199
+ Accessibility,Accessibility Testing Automation,All,High,accessibility testing espresso robolectric scanner automated a11y compose,No automated accessibility testing; manual testing misses issues,Use Espresso accessibility checks and Accessibility Scanner; add to CI pipeline,Manual accessibility testing only; issues found after release,"// Compose test: composeTestRule.onNodeWithText(""Submit"").assertHasClickAction().assert(hasContentDescription()); // Espresso: AccessibilityChecks.enable()",// No accessibility tests in CI; discover issues from user complaints post-launch,Zero a11y violations in CI,https://developer.android.com/develop/ui/compose/testing#accessibility-checks
200
+ Network,Adaptive Network Quality,All,High,network quality adaptive bandwidth 2g 3g 4g 5g wifi degrade graceful,Same behavior on 2G as on 5G; timeouts and failures on slow networks,Detect network quality; adapt content and timeout; show low-quality images on slow connections,Same image quality and timeouts regardless of connection speed,val quality = if (connectivityManager.isActiveNetworkMetered) ImageQuality.LOW else ImageQuality.HIGH; // Adapt content to network,// Always load 4K images; 30s timeout on 2G; app appears frozen; user gives up,Adaptive to network speed,https://developer.android.com/training/basics/network-ops/managing
201
+ Network,Exponential Backoff Retry,All,High,retry exponential backoff jitter network failure resilience robust api,Fixed retry interval hammering server during outage; making problem worse,Implement exponential backoff with jitter for retries; max retry limit,Retry immediately in tight loop; 1000 retries/sec during server outage,delay(minOf(baseDelay * 2.0.pow(attempt) maxDelay) + Random.nextLong(0 jitter)); // Exponential + jitter,while(true) { try { api.call(); break } catch(e: Exception) { /* retry immediately */ } } // Hammers server,Exponential backoff,https://developer.android.com/training/efficient-downloads
202
+ Network,ETag and Conditional Requests,All,Medium,etag conditional request 304 not modified cache validation bandwidth,Re-downloading unchanged data every time; wasting bandwidth,Use ETag/If-None-Match for conditional requests; server returns 304 when unchanged,Full response every request even when data hasn't changed; wastes bandwidth,// OkHttp cache: Cache(cacheDir 50L * 1024 * 1024); // Automatic ETag/304 handling,// No cache headers; 100KB response re-downloaded every 30s even when unchanged,304 for unchanged data,https://developer.android.com/training/efficient-downloads/regular-updates
203
+ Network,DNS Prefetch and Connection Warmup,All,Medium,dns prefetch warmup connection prewarm latency cold start api,First API call slow due to DNS resolution + TLS handshake overhead,Prefetch DNS and warm connections during splash/onboarding,First real API call incurs 500ms+ DNS + TLS overhead,// OkHttp: client.connectionPool(); // Prewarm: lifecycleScope.launch { okHttpClient.newCall(Request.Builder().url(baseUrl).head().build()).execute() },// First API call takes 800ms: DNS(200ms) + TCP(150ms) + TLS(300ms) + request(150ms),< 200ms first API call,https://square.github.io/okhttp/features/connections/
204
+ Scalability,Multi-Module Architecture,Android,Critical,multi module modularization feature core data domain scale team,Monolithic single-module app; merge conflicts; slow builds; can't parallelize,Split into feature/core/domain modules; clear dependency rules; module per feature team,Single :app module with everything; 10 developers all editing same module,// :core:data :core:ui :core:network :feature:home :feature:search :feature:profile; // Each team owns their feature module,// Single :app module; 500 files; every PR conflicts; 8min clean build; can't assign ownership,< 2min incremental build,https://developer.android.com/topic/modularization
205
+ Scalability,API Versioning Strategy,All,High,api versioning backward compatible migration deprecated endpoint mobile,Breaking API changes crashing older app versions still in the wild,Version APIs; maintain backward compatibility; force update only for critical changes,Unversioned API; breaking changes affect all users including those who can't update,// api/v2/users; // Server maintains v1 and v2; // App checks minimum version: if (serverMinVersion > appVersion) forceUpdate(),// /api/users changes response format; all apps < v2.0 crash; 40% of users affected,Zero breaking changes,https://developer.android.com/guide/playcore/in-app-updates
206
+ Scalability,Feature Flags for Gradual Rollout,All,High,feature flag toggle rollout ab test remote config firebase gradual,Big-bang releases with all features at once; risky deployments,Use feature flags for gradual rollout; A/B testing; instant kill switch,Deploy everything at once; no way to disable broken feature without new release,"if (remoteConfig.getBoolean(""new_checkout_enabled"")) { NewCheckoutScreen() } else { OldCheckoutScreen() }",// Ship new checkout to 100% of users at once; discover bug; 24h to fix and release; all users affected,Gradual rollout per feature,https://firebase.google.com/docs/remote-config
207
+ Scalability,Offline-First Data Sync,All,High,offline first sync conflict resolution local database room queue retry,App unusable without internet; loading spinner until network available,Design offline-first; queue mutations; sync when online; resolve conflicts,Show blank screen or error when offline; lose user's unsaved work,// Room as source of truth; queue pending mutations; WorkManager syncs when online; merge conflicts server-side,"// if (!isOnline) showError(""No internet""); // App useless offline; user loses drafted message",Fully functional offline,https://developer.android.com/topic/architecture/data-layer/offline-first
208
+ Scalability,Pagination for All Lists,All,High,pagination infinite scroll paging3 cursor offset limit load more,Loading entire dataset into memory; OOM on large lists; slow initial load,Paginate all lists; use cursor-based pagination; load 20 items at a time,SELECT * with no LIMIT; load 10000 items into memory; 5s initial load,val pager = Pager(PagingConfig(pageSize = 20 prefetchDistance = 5)) { pagingSource }.flow.cachedIn(viewModelScope),val items = api.getAllItems() // Returns 10000 items; 5s load; OOM on low memory devices,Load 20 items per page,https://developer.android.com/topic/libraries/architecture/paging/v3-overview
209
+ CI/CD,Automated Build Pipeline,All,Critical,ci cd pipeline github actions bitrise fastlane automated build deploy,No CI/CD; manual builds and deploys; human error in releases,Set up automated CI pipeline: lint > test > build > deploy; gate on quality,Manual APK/IPA generation on developer machine; error-prone releases,// .github/workflows/android.yml: on push: run lint > unit test > instrumented test > assemble > deploy to Play Store,// Developer runs ./gradlew assembleRelease manually; forgets to run tests; ships broken build,Fully automated pipeline,https://developer.android.com/studio/publish
210
+ CI/CD,Automated Code Quality Gates,All,High,lint detekt ktlint spotless quality gate ci merge block,No code quality enforcement; inconsistent code merged,Block merge on lint errors detekt warnings and test failures,Allow any code to merge regardless of quality; fix later,// CI: ./gradlew detekt ktlintCheck lint testDebugUnitTest; // Fails PR if any issue found,// No quality gates; merge at will; codebase degrades over time; 500+ lint warnings ignored,Zero warnings policy,https://detekt.dev/
211
+ CI/CD,Test Coverage Tracking,All,Medium,test coverage jacoco kover lcov report minimum threshold ci,No coverage tracking; unknown how much code is tested,Track coverage with Kover/JaCoCo; set minimum thresholds; fail CI below threshold,No coverage reports; claim 'we have tests' without data,// build.gradle: kover { reports { total { verify { rule { minBound(80) } } } } }; // CI: ./gradlew koverVerify,// No coverage tracking; 15% actual coverage but assumed to be 'good enough',≥ 80% line coverage,https://github.com/Kotlin/kotlinx-kover
212
+ Monitoring,Crash Reporting Setup,All,Critical,crash reporting crashlytics sentry bugsnag firebase production monitoring,No crash reporting; bugs discovered from user reviews,Integrate crash reporting from day 1; set up alerts for new crashes,No crash monitoring; discover crashes from 1-star reviews weeks later,FirebaseCrashlytics.getInstance().setUserId(userId); // Plus: non-fatal logging for caught exceptions,// No crash reporting SDK; users see crashes; team unaware until Play Store rating drops,< 0.1% crash rate,https://firebase.google.com/docs/crashlytics
213
+ Monitoring,ANR Rate Monitoring,Android,High,anr rate vitals play console monitoring main thread block production,Not monitoring ANR rate in production; bad Play Store ranking,Monitor ANR rate via Play Vitals; set up alerts; target < 0.47%,Ignore Play Console vitals; ANR rate > 2%; bad search ranking,// Firebase Performance + Play Vitals dashboard; alert on ANR rate > 0.47%; fix main thread violations,// Never check Play Console; ANR rate 3.5%; app demoted in Play Store search results,< 0.47% ANR rate,https://developer.android.com/topic/performance/vitals/anr
214
+ Monitoring,Performance Monitoring in Production,All,Medium,performance monitoring firebase trace custom metric latency percentile production,Only testing performance on developer device; production varies wildly,Use Firebase Performance or custom traces; monitor p50/p95/p99 latency,Test on high-end device only; users on budget devices see 5s load times,"val trace = Firebase.performance.newTrace(""load_home""); trace.start(); /*...*/ trace.stop()",// No production monitoring; app takes 8s to load on Samsung A14; team unaware,Monitor p95 latency,https://firebase.google.com/docs/perf-mon
215
+ Navigation,Deep Link Handling,Android,High,deep link app link uri navigation deferred verify intent,No deep link support; users can't share or bookmark app content,Implement verified App Links; handle deferred deep links for installs,No deep links; sharing sends to website not app; lost users,"// AndroidManifest: <intent-filter autoVerify=""true"">; <data android:scheme=""https"" android:host=""app.example.com"" />; // Handle in NavHost",// No deep links; user shares URL; recipient opens browser instead of app; poor experience,Deep link opens correct screen,https://developer.android.com/training/app-links
216
+ Navigation,Push Notification Navigation,All,High,push notification navigation deep link payload click route fcm apns,Push notification opens app but doesn't navigate to relevant screen,Parse notification payload; navigate to correct screen on tap,Tap notification opens home screen; user must manually find content,"// FCM data payload: {""screen"": ""order_detail"" ""id"": ""123""}; // On tap: navController.navigate(OrderDetail(id))",// All notifications open MainActivity; user taps 'Your order shipped' but sees home feed,Notification → correct screen,https://developer.android.com/develop/ui/views/notifications
217
+ Storage,DataStore Migration from SharedPreferences,Android,Medium,datastore migration sharedpreferences proto preferences async coroutine,Still using SharedPreferences; I/O on main thread; no type safety,Migrate to DataStore Preferences or Proto; async operations; type safe,SharedPreferences.edit().putString() on main thread; blocks UI during disk write,"val dataStore = context.createDataStore(""settings""); val flow = dataStore.data.map { it[KEY] }; // Async; Flow-based","context.getSharedPreferences(""prefs"" MODE_PRIVATE).edit().putString(""key"" value).apply() // Can block main thread",Async storage access,https://developer.android.com/topic/libraries/architecture/datastore
218
+ Permissions,Runtime Permission Best Practices,Android,High,permission runtime request rationale context location camera storage,Requesting all permissions at launch; no rationale; poor UX,Request permissions in context; show rationale before; handle denial gracefully,Request camera + location + storage + contacts all at once on first launch,// Request camera permission only when user taps camera button; show rationale if shouldShowRequestPermissionRationale,// onCreate: requestPermissions(arrayOf(CAMERA LOCATION STORAGE CONTACTS)) // All at once; no context; scary,In-context permission requests,https://developer.android.com/training/permissions/requesting
219
+ Localization,RTL Layout Support,All,Medium,rtl layout right to left arabic hebrew bidirectional text direction,App breaks in RTL languages; text overlapping; layouts mirrored wrong,Use start/end instead of left/right; test with RTL pseudolocale; support Bidi text,Hardcoded left/right margins; layout breaks in Arabic/Hebrew,Modifier.padding(start = 16.dp end = 8.dp) // Works for both LTR and RTL,Modifier.padding(PaddingValues(left = 16.dp right = 8.dp)) // Breaks in RTL; text overlaps,Works in RTL languages,https://developer.android.com/develop/ui/views/layout/rtl
220
+ Localization,Pluralization and ICU,All,Medium,plural icu message format localization quantity string translation,Naive string concatenation for plurals; wrong in many languages,Use Quantity Strings (plurals) and ICU MessageFormat for proper localization,"""You have "" + count + "" items"" // Wrong in Russian Polish Arabic etc",pluralStringResource(R.plurals.items_count count count) // Handles one few many other,"""You have $count item"" + if (count > 1) ""s"" else """" // Fails for 0 items; wrong in most languages",Correct pluralization,https://developer.android.com/guide/topics/resources/string-resource#Plurals
221
+ Background,WorkManager Best Practices,Android,High,workmanager background work periodic oneoff chain constraint retry,Incorrect background work scheduling; tasks fail or drain battery,Use WorkManager with constraints; chain work; handle retries with exponential backoff,AlarmManager setExact for background tasks; custom Services running indefinitely,val work = OneTimeWorkRequestBuilder<SyncWorker>().setConstraints(Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED).build()).setBackoffCriteria(BackoffPolicy.EXPONENTIAL 10 TimeUnit.SECONDS).build(),// AlarmManager running every 15min without constraints; drains battery; killed by Doze,Work survives process death,https://developer.android.com/topic/libraries/architecture/workmanager
222
+ Background,Foreground Service Compliance,Android,Critical,foreground service type notification android 14 15 compliance background,Foreground services without proper type declaration; rejected on Android 14+,Declare foreground service type; show notification; end service promptly,Foreground service without type; runs indefinitely; violates Android 14+ policy,"<service android:foregroundServiceType=""location"" />; startForeground(NOTIFICATION_ID builder.build())",// startForeground() with no foregroundServiceType; // crashes on Android 14; Play Store rejection,Correct service type declared,https://developer.android.com/develop/background-work/services/foreground-services
223
+ Background,Background Task Scheduling iOS,iOS,High,ios background task scheduler bgtaskscheduler fetch processing apprefresh,iOS background tasks not properly scheduled; killed by system,Use BGTaskScheduler for background work; register identifiers; handle expiration,URLSession.dataTask in applicationDidEnterBackground; killed after 30s,"BGTaskScheduler.shared.register(forTaskWithIdentifier: ""refresh"" using: nil) { task in /*...*/ task.setTaskCompleted(success: true) }",// Timer.scheduledTimer in background; killed by iOS; no data refresh while suspended,Background refresh works,https://developer.apple.com/documentation/backgroundtasks
224
+ Analytics,Event Tracking Architecture,All,Medium,analytics event tracking firebase amplitude mixpanel architecture pattern,Ad-hoc analytics scattered through codebase; inconsistent naming; missed events,Create analytics abstraction layer; consistent naming convention; central event catalog,Analytics.track() calls scattered in Views/VMs with inconsistent names,interface AnalyticsTracker { fun track(event: AnalyticsEvent) }; sealed class AnalyticsEvent { data class ScreenView(val name: String) : AnalyticsEvent() },"// Every file: Firebase.analytics.logEvent(""btn_click"" bundleOf(""x"" to y)); // Inconsistent; no catalog; duplicated",Centralized event catalog,https://firebase.google.com/docs/analytics
225
+ Analytics,User Properties and Segmentation,All,Medium,analytics user property segment cohort attribute retention engagement,No user segmentation; can't analyze feature usage by cohort,Set user properties for segmentation; track feature adoption by user type,One-size-fits-all analytics; can't tell if paid users vs free use feature differently,"Firebase.analytics.setUserProperty(""plan_type"" ""premium""); setUserProperty(""app_version"" BuildConfig.VERSION_NAME)",// No user properties; can't segment data; 'feature used 1000 times' but by how many users?,Segment by user cohort,https://firebase.google.com/docs/analytics/user-properties
226
+ Updates,In-App Update Prompt,Android,Medium,in app update flexible immediate play store prompt version,Users stuck on old versions; no prompt to update,Use Play In-App Updates API; flexible for minor; immediate for critical,No update mechanism; rely on auto-update which many disable,val manager = AppUpdateManagerFactory.create(context); manager.appUpdateInfo.addOnSuccessListener { if (it.updateAvailability() == UPDATE_AVAILABLE) startUpdate(it) },// No update check; users stay on v1.0 for years; miss critical fixes; support burden,< 2 versions behind,https://developer.android.com/guide/playcore/in-app-updates
227
+ Updates,Force Update for Critical Fixes,All,High,force update minimum version remote config critical security patch,Critical security or crash fix but users on old versions,Implement minimum version check via Remote Config; force update for security fixes,No force update; critical vulnerability exists but 30% users on unfixed version,"// Remote Config: minimum_version = ""2.1.0""; if (currentVersion < minimumVersion) showForceUpdateDialog()",// Critical security fix in v2.1; 30% users on v2.0; no way to force update; data breach,100% on patched version,https://firebase.google.com/docs/remote-config
228
+ Dependencies,Dependency Update Strategy,All,Medium,dependency update renovate dependabot outdated library version bot automated,Dependencies never updated; 2+ years behind; security vulnerabilities,Use Renovate or Dependabot for automated PRs; update monthly; pin versions,Never update deps; 'if it works don't touch it'; 3-year-old libraries with CVEs,"// .github/renovate.json: { ""extends"": [""config:recommended""] ""schedule"": [""every weekend""] }",// dependencies { implementation 'com.squareup.retrofit2:retrofit:2.3.0' } // 5 years old; known CVEs,< 1 minor version behind,https://docs.github.com/en/code-security/dependabot
229
+ Dependencies,Transitive Dependency Conflicts,Android,Medium,transitive dependency conflict resolution exclude force version alignment,Conflicting transitive dependency versions causing runtime crashes,Use Gradle dependency constraints; BOM for version alignment; resolve conflicts explicitly,Ignore version conflicts; random ClassNotFoundException at runtime,"// constraints { implementation(""com.google.guava:guava:33.0.0-android"") }; // Or: BOM approach",// Conflicting okio versions: 2.x from retrofit + 3.x from okhttp; ClassNotFoundException at runtime,Zero version conflicts,https://docs.gradle.org/current/userguide/dependency_constraints.html