Compose 性能优化利器:derivedStateOf 核心详解
简单来说,derivedStateOf 是 Compose 中的「状态加工厂」。
它的作用是:把一个或多个频繁变化 的状态,加工成一个只在关键结果改变时 才触发重组的新状态。
它是 Compose 性能优化中最重要的工具之一,专门用来减少不必要的重组。
1. 为什么需要它?(场景对比)
想象一个场景:你有一个列表,当滑动超过 100 像素时,显示一个"回到顶部"按钮。
❌ 错误写法(性能黑洞)
kotlin
val scrollOffset = scrollState.value // 滑一下会产生几十次数值变化
val showButton = scrollOffset > 100
if (showButton) { ... }
- 问题:
scrollOffset每 1 像素都会变化,UI 每秒重组几十次 - 结果:手机发烫、界面卡顿
✅ 正确写法(使用 derivedStateOf)
kotlin
val showButton by remember {
derivedStateOf {
scrollState.value > 100 // 仅布尔结果变化时,才触发重组
}
}
if (showButton) { ... }
- 优化:
derivedStateOf是过滤器,计算结果不变就不通知 UI,彻底避免无效重组
2. derivedStateOf vs remember(key) 核心区别
| 特性 | remember(key) | derivedStateOf |
|---|---|---|
| 关注点 | 依赖项(Key)的变化 | 计算结果的变化 |
| 重组触发 | 只要 Key 变,就重组 | 只有最终结果变,才重组 |
| 核心用途 | 类型转换、从 Model 取值 | 高频状态逻辑过滤(滑动、表单、搜索) |
remember(key):依赖变 → 重新计算 + 强制重组derivedStateOf:依赖变 → 重新计算 → 结果不变则不重组
3. 最佳使用场景
记住准则:状态变化频率 > UI 需要刷新频率时,必用 derivedStateOf
高频使用场景:
- 滑动监听:列表滑动距离判断、滑到指定项显示按钮
- 表单验证:用户名+密码都合法时,才启用登录按钮
- 搜索过滤:输入关键词过滤列表,仅最终结果变化刷新
- 分页/轮播判断:ViewPager 滑到最后一页显示提示
4. 核心总结
derivedStateOf 是 Compose 的减震器:
- 监控高频变动的"好动"状态
- 仅在计算出有意义的结果变化时,通知 UI 刷新
- 大幅减少无效重组,让界面极致流畅
一句话口诀
高频状态转低频,逻辑过滤是核心;只要结果没改变,UI 稳坐不动心。