📐 Compose 性能模型

重组 · 布局 · 绘制

⚡ Compose 渲染管线 基于 重组(Recomposition) + 三阶段流水线 (组合/布局/绘制)。 理解性能模型是优化卡顿的基石。以下拆解核心机制。

🔁 1. 渲染管线 & 重组机制 Recomposition
组合 Composition (重组触发) 布局 Layout (测量·放置) 绘制 Drawing (Canvas·Skia) 状态变化 → 重组循环
📐 2. 布局与绘制三阶段 Layout · Drawing
阶段 主要工作 性能关键点 优化提示
① 组合 (Composition) 执行 Composable 函数,生成/更新 LayoutNode 树 重组频率、lambda 捕获、稳定性 使用 remember / derivedStateOf 缩小范围
② 布局 (Layout) 测量 (Measure) + 放置 (Place) 子节点 测量次数、固有特性测量、深层次树 避免多次测量;使用 Modifier.layout 自定义
③ 绘制 (Drawing) Canvas 绘制、Shader、Clip、Path 等 过度绘制、复杂 Path、Bitmap 上传 减少重绘区域;使用 drawWithCache

💡 重组与三阶段的关系:

重组仅触发 组合阶段,但可能连带引起布局/绘制。Compose 使用跳过无效阶段优化:若组合结果未改变布局/绘制数据,则跳过后续阶段。

🧪 3. 代码示例 · 重组与性能 实践
// 不稳定示例:每次重组都会执行大量计算
@Composable
fun HeavyComposable(counter: Int) {
    val result = remember(counter) {
        // 模拟耗时计算
        (0..1000).sumOf { it * counter }
    }
    Text("结果: $result")
}

// ✅ 稳定优化:使用 derivedStateOf 缩小重组
@Composable
fun OptimizedList(items: List<String>, query: String) {
    val filtered = remember(items, query) {
        derivedStateOf { items.filter { it.contains(query) } }
    }
    LazyColumn {
        items(filtered.value) { item -> Text(item) }
    }
}
类型分类示例稳定性建议
原始类型Int, Float, Boolean稳定直接使用
StringString稳定不可变,放心
数据类 (所有参数 var)data class User(var name: String)不稳定使用 @Stable 或改为 val
List / MapList<String>不稳定使用 immutableList 或 remember