最佳实践清单 (Best Practices)
这是一份 Code Review 时的检查清单,涵盖了性能、正确性和架构。
✅ 性能 (Performance)
- 使用
remember: 任何计算量大的操作(过滤列表、格式化日期)都应该被remember。 - 推迟状态读取: 优先在
Modifier.offset {}(Lambda) 中读取状态,而不是直接读取,以跳过 Composition 阶段。 - Key 的使用: 在
LazyColumn和Column/Row(配合for) 中,始终显式指定key。 - 避免
derivedStateOf滥用: 只在状态更新频率 > 重组频率时使用(如滚动偏移量转布尔值)。 - R8 优化: 确保 Release 包开启了 R8,Compose 极其依赖 R8 的优化。
✅ 正确性 (Correctness)
- 无副作用: Composable 函数体应该是纯函数。副作用必须放入
LaunchedEffect或DisposableEffect。 - Context 引用: 不要把
Context或View存入 ViewModel,这会导致内存泄漏。 - Flow 收集: 在 UI 层收集 Flow 时,必须使用
collectAsStateWithLifecycle()(需引入androidx.lifecycle:lifecycle-runtime-compose),而不是简单的collectAsState(),否则应用后台时流不会停止。
✅ 架构 (Architecture)
- 状态提升: 子组件应尽量无状态 (Stateless),只接收数据和回调。
- 单一数据源: 确保数据来自 ViewModel/Repository,而不是在 UI 层临时创建。
- 插槽 API (Slot API): 优先设计接受
content: @Composable () -> Unit的组件,而不是接受数据对象的组件,这样更灵活。
🚫 反模式 (Anti-Patterns)
- 向上传递 State: 不要把
MutableState传给父组件让父组件修改。应该传递回调(T) -> Unit。 - 过早优化: 不要到处加
@Stable,先用编译器报告分析瓶颈。 - ViewModel 传入子组件: 尽量只在 Screen 级别获取 ViewModel,子组件只接收简单参数。