perf: 限制 WebP 动画重复次数并简化入场动画,减少帧丢失
Perfetto trace 分析显示 75.6% 帧延迟,根因为 250x250 WebP 持续以 11-14 FPS 无限循环解码。每次解码周期导致 4-26 帧延迟。 - AnimatedGif: repeatCount(2) 限制动画播放 3 次后停止 - AnimatedGif: 移除两阶段弹跳动画,改为 150ms 淡入 - README: 添加构建命令和产物路径
This commit is contained in:
parent
a84e1b9528
commit
80ab328906
26
README.md
26
README.md
@ -19,4 +19,30 @@
|
||||
- 双模块:`:shared`(UI + 逻辑) · `:androidApp`(薄壳)
|
||||
- iOS 入口为 `MainViewController.kt`,Xcode 工程位于 `iosApp/`
|
||||
|
||||
## 构建
|
||||
|
||||
```bash
|
||||
# Debug
|
||||
./gradlew :app:assembleDebug # 构建 debug APK
|
||||
./gradlew :app:installDebug # 安装 debug APK 到设备
|
||||
|
||||
# Release
|
||||
./gradlew :app:assembleRelease # 构建 release APK
|
||||
./gradlew :app:installBenchmark # 安装 benchmark(release + 可调试)APK
|
||||
|
||||
# 测试
|
||||
./gradlew :core:testDebugUnitTest # 运行全部测试
|
||||
./gradlew :core:testDebugUnitTest --tests "plus.rua.project.ui.CalendarUtilsTest" # 运行单个测试
|
||||
|
||||
# Baseline Profile(需要连接设备)
|
||||
./gradlew :macrobenchmark:updateBaselineProfile # 一键生成 + 自动复制到 :core
|
||||
./gradlew :macrobenchmark:connectedBenchmarkAndroidTest # 仅运行基准测试
|
||||
|
||||
# 性能 Profiling(需要连接设备)
|
||||
./scripts/profile.sh # 默认 8 秒
|
||||
./scripts/profile.sh 15 # 自定义时长
|
||||
```
|
||||
|
||||
构建产物位于 `app/build/outputs/apk/<variant>/` 目录。
|
||||
|
||||
线条小狗表情包来自 https://www.douban.com/group/topic/264788645/?_i=9181692phrDzjR,9241256phrDzjR
|
||||
|
||||
@ -2,8 +2,6 @@ package plus.rua.project.ui
|
||||
|
||||
import androidx.compose.animation.core.Animatable
|
||||
import androidx.compose.animation.core.FastOutSlowInEasing
|
||||
import androidx.compose.animation.core.Spring
|
||||
import androidx.compose.animation.core.spring
|
||||
import androidx.compose.animation.core.tween
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
@ -11,6 +9,9 @@ import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.graphicsLayer
|
||||
import com.github.panpf.sketch.AsyncImage
|
||||
import com.github.panpf.sketch.rememberAsyncImageState
|
||||
import com.github.panpf.sketch.request.ImageOptions
|
||||
import com.github.panpf.sketch.request.repeatCount
|
||||
import plus.rua.project.getWebpUri
|
||||
|
||||
/**
|
||||
@ -18,12 +19,16 @@ import plus.rua.project.getWebpUri
|
||||
*/
|
||||
private val WEBP_FILES = (1..152).map { "${it.toString().padStart(3, '0')}.webp" }
|
||||
|
||||
private const val REPEAT_COUNT = 2
|
||||
|
||||
/**
|
||||
* 显示动画 GIF 图片,切换日期时随机选择一个。
|
||||
* 显示动画 WebP 图片,切换日期时随机选择一个。
|
||||
*
|
||||
* 动画播放 3 次(1 + [REPEAT_COUNT])后停止,避免持续解码导致的帧丢失。
|
||||
*
|
||||
* @param modifier 应用于图片的 Modifier
|
||||
* @param contentDescription 无障碍描述
|
||||
* @param seed 用于控制重新随机时机的 key,变化时重新选择 GIF
|
||||
* @param seed 用于控制重新随机时机的 key,变化时重新选择 WebP
|
||||
*/
|
||||
@Composable
|
||||
fun AnimatedGif(
|
||||
@ -33,28 +38,26 @@ fun AnimatedGif(
|
||||
) {
|
||||
val webpFile = remember(seed) { WEBP_FILES.random() }
|
||||
val uri = remember(webpFile) { getWebpUri(webpFile) }
|
||||
val scale = remember { Animatable(0f) }
|
||||
val alpha = remember { Animatable(0f) }
|
||||
|
||||
LaunchedEffect(seed) {
|
||||
scale.snapTo(0f)
|
||||
scale.animateTo(
|
||||
targetValue = 1.1f,
|
||||
animationSpec = tween(250, easing = FastOutSlowInEasing),
|
||||
)
|
||||
scale.animateTo(
|
||||
alpha.snapTo(0f)
|
||||
alpha.animateTo(
|
||||
targetValue = 1f,
|
||||
animationSpec = spring(dampingRatio = Spring.DampingRatioMediumBouncy),
|
||||
animationSpec = tween(150, easing = FastOutSlowInEasing),
|
||||
)
|
||||
}
|
||||
|
||||
val state = rememberAsyncImageState(
|
||||
options = remember { ImageOptions { repeatCount(REPEAT_COUNT) } }
|
||||
)
|
||||
|
||||
AsyncImage(
|
||||
uri = uri,
|
||||
contentDescription = contentDescription,
|
||||
modifier = modifier
|
||||
.graphicsLayer {
|
||||
scaleX = scale.value
|
||||
scaleY = scale.value
|
||||
alpha = scale.value.coerceIn(0f, 1f)
|
||||
},
|
||||
state = state,
|
||||
modifier = modifier.graphicsLayer {
|
||||
this.alpha = alpha.value
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user