mirror of
https://github.com/pawelorzech/Swoosh.git
synced 2026-03-31 20:15:41 +00:00
perf: remove StaggeredItem animations from LazyColumn for smooth scrolling
StaggeredItem wrapped every list item in AnimatedVisibility with slideInVertically + fadeIn + LaunchedEffect delays, causing jittery scrolling due to excessive recompositions and layout passes.
This commit is contained in:
parent
c3fb3c7c98
commit
f3ab562a6c
1 changed files with 32 additions and 90 deletions
|
|
@ -129,8 +129,7 @@ fun FeedScreen(
|
|||
var showRenameDialog by remember { mutableStateOf<GhostAccount?>(null) }
|
||||
|
||||
// Staggered entrance tracking
|
||||
val animatedKeys = remember { mutableStateMapOf<String, Boolean>() }
|
||||
var initialLoadComplete by remember { mutableStateOf(false) }
|
||||
// Stagger animations removed for smooth scrolling performance
|
||||
|
||||
// FAB entrance animation
|
||||
var fabVisible by remember { mutableStateOf(false) }
|
||||
|
|
@ -535,12 +534,6 @@ fun FeedScreen(
|
|||
key = { it.ghostId ?: "local_${it.localId}" },
|
||||
contentType = { "search_post" }
|
||||
) { post ->
|
||||
val itemKey = post.ghostId ?: "local_${post.localId}"
|
||||
StaggeredItem(
|
||||
key = itemKey,
|
||||
animatedKeys = animatedKeys,
|
||||
initialLoadComplete = initialLoadComplete
|
||||
) {
|
||||
PostCard(
|
||||
post = post,
|
||||
onClick = { onPostClick(post) },
|
||||
|
|
@ -548,7 +541,6 @@ fun FeedScreen(
|
|||
highlightQuery = searchQuery
|
||||
)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Normal feed: pinned section + swipe actions
|
||||
// Pinned posts (pin icon on each post card is sufficient)
|
||||
|
|
@ -558,12 +550,6 @@ fun FeedScreen(
|
|||
key = { "pinned_${it.ghostId ?: "local_${it.localId}"}" },
|
||||
contentType = { "pinned_post" }
|
||||
) { post ->
|
||||
val itemKey = post.ghostId ?: "local_${post.localId}"
|
||||
StaggeredItem(
|
||||
key = itemKey,
|
||||
animatedKeys = animatedKeys,
|
||||
initialLoadComplete = initialLoadComplete
|
||||
) {
|
||||
SwipeablePostCard(
|
||||
post = post,
|
||||
onClick = { onPostClick(post) },
|
||||
|
|
@ -582,7 +568,6 @@ fun FeedScreen(
|
|||
snackbarHostState = snackbarHostState
|
||||
)
|
||||
}
|
||||
}
|
||||
// No extra separator — thick dividers built into each post
|
||||
}
|
||||
|
||||
|
|
@ -591,12 +576,6 @@ fun FeedScreen(
|
|||
key = { it.ghostId ?: "local_${it.localId}" },
|
||||
contentType = { "regular_post" }
|
||||
) { post ->
|
||||
val itemKey = post.ghostId ?: "local_${post.localId}"
|
||||
StaggeredItem(
|
||||
key = itemKey,
|
||||
animatedKeys = animatedKeys,
|
||||
initialLoadComplete = initialLoadComplete
|
||||
) {
|
||||
SwipeablePostCard(
|
||||
post = post,
|
||||
onClick = { onPostClick(post) },
|
||||
|
|
@ -616,7 +595,6 @@ fun FeedScreen(
|
|||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!isSearchActive && state.isLoadingMore) {
|
||||
item {
|
||||
|
|
@ -630,14 +608,6 @@ fun FeedScreen(
|
|||
}
|
||||
}
|
||||
|
||||
LaunchedEffect(state.posts) {
|
||||
if (state.posts.isNotEmpty() && !initialLoadComplete) {
|
||||
delay(SwooshMotion.StaggerDelayMs * minOf(state.posts.size, 8) + 200)
|
||||
initialLoadComplete = true
|
||||
animatedKeys.clear() // Free memory — no longer needed
|
||||
}
|
||||
}
|
||||
|
||||
if (!isSearchActive) {
|
||||
PullRefreshIndicator(
|
||||
refreshing = state.isRefreshing,
|
||||
|
|
@ -766,34 +736,6 @@ fun FeedScreen(
|
|||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun StaggeredItem(
|
||||
key: String,
|
||||
animatedKeys: MutableMap<String, Boolean>,
|
||||
initialLoadComplete: Boolean,
|
||||
content: @Composable () -> Unit
|
||||
) {
|
||||
val shouldAnimate = !initialLoadComplete && key !in animatedKeys
|
||||
var visible by remember { mutableStateOf(!shouldAnimate) }
|
||||
|
||||
LaunchedEffect(key) {
|
||||
if (shouldAnimate && animatedKeys.size < 8) {
|
||||
delay(SwooshMotion.StaggerDelayMs * animatedKeys.size)
|
||||
animatedKeys[key] = true
|
||||
}
|
||||
visible = true
|
||||
}
|
||||
|
||||
AnimatedVisibility(
|
||||
visible = visible,
|
||||
enter = slideInVertically(
|
||||
initialOffsetY = { it / 3 },
|
||||
animationSpec = SwooshMotion.gentle()
|
||||
) + fadeIn(animationSpec = SwooshMotion.quick())
|
||||
) {
|
||||
content()
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
|
|
|
|||
Loading…
Reference in a new issue