perf(ui): drop remember wrappers where overhead exceeds savings
Cases removed: - Trivial Modifier allocations (Modifier.weight/padding/size) — slot table cost dominates the cost of building a fresh Modifier each recomposition. - Map.keys views over relayStatuses on desktop screens — .keys is a property read on the same map, no need to memoize. - coerceIn() arithmetic on AudioWaveform Dp/Float params — two compares are cheaper than the slot table read+compare. - fadeIn()/fadeOut() in AnimatedVisibility — small EnterTransition allocations that don't justify the slot table overhead. Audit-only changes; no behavior changes. https://claude.ai/code/session_011Ea2pVjwvCEx7X4izwryV4
This commit is contained in:
+5
-9
@@ -78,15 +78,11 @@ fun AudioWaveformReadOnly(
|
||||
amplitudes: List<Float>,
|
||||
onProgressChange: (Float) -> Unit,
|
||||
) {
|
||||
val progressState = remember(progress) { progress.coerceIn(MIN_PROGRESS, MAX_PROGRESS) }
|
||||
val spikeWidthState =
|
||||
remember(spikeWidth) { spikeWidth.coerceIn(MinSpikeWidthDp, MaxSpikeWidthDp) }
|
||||
val spikePaddingState =
|
||||
remember(spikePadding) { spikePadding.coerceIn(MinSpikePaddingDp, MaxSpikePaddingDp) }
|
||||
val spikeRadiusState =
|
||||
remember(spikeRadius) { spikeRadius.coerceIn(MinSpikeRadiusDp, MaxSpikeRadiusDp) }
|
||||
val spikeTotalWidthState =
|
||||
remember(spikeWidth, spikePadding) { spikeWidthState + spikePaddingState }
|
||||
val progressState = progress.coerceIn(MIN_PROGRESS, MAX_PROGRESS)
|
||||
val spikeWidthState = spikeWidth.coerceIn(MinSpikeWidthDp, MaxSpikeWidthDp)
|
||||
val spikePaddingState = spikePadding.coerceIn(MinSpikePaddingDp, MaxSpikePaddingDp)
|
||||
val spikeRadiusState = spikeRadius.coerceIn(MinSpikeRadiusDp, MaxSpikeRadiusDp)
|
||||
val spikeTotalWidthState = spikeWidthState + spikePaddingState
|
||||
var canvasSize by remember { mutableStateOf(Size(0f, 0f)) }
|
||||
var spikes by remember { mutableFloatStateOf(0F) }
|
||||
val spikesAmplitudes =
|
||||
|
||||
+2
-2
@@ -334,8 +334,8 @@ private fun DialogContent(
|
||||
|
||||
AnimatedVisibility(
|
||||
visible = controllerVisible.value,
|
||||
enter = remember { fadeIn() },
|
||||
exit = remember { fadeOut() },
|
||||
enter = fadeIn(),
|
||||
exit = fadeOut(),
|
||||
// Also fade with the grow animation so controls appear/disappear alongside it.
|
||||
modifier = Modifier.graphicsLayer { alpha = progress().coerceIn(0f, 1f) },
|
||||
) {
|
||||
|
||||
+4
-4
@@ -404,8 +404,8 @@ fun LocalImageView(
|
||||
AnimatedVisibility(
|
||||
visible = controllerVisible.value,
|
||||
modifier = Modifier.align(Alignment.TopEnd),
|
||||
enter = remember { fadeIn() },
|
||||
exit = remember { fadeOut() },
|
||||
enter = fadeIn(),
|
||||
exit = fadeOut(),
|
||||
) {
|
||||
Box(Modifier.align(Alignment.TopEnd), contentAlignment = Alignment.TopEnd) {
|
||||
HashVerificationSymbol(it)
|
||||
@@ -649,8 +649,8 @@ fun ShowHashAnimated(
|
||||
AnimatedVisibility(
|
||||
visible = controllerVisible.value,
|
||||
modifier = modifier,
|
||||
enter = remember { fadeIn() },
|
||||
exit = remember { fadeOut() },
|
||||
enter = fadeIn(),
|
||||
exit = fadeOut(),
|
||||
) {
|
||||
Box(modifier, contentAlignment = Alignment.TopEnd) {
|
||||
ShowHash(content)
|
||||
|
||||
@@ -332,7 +332,7 @@ fun RenderZapGallery(
|
||||
modifier = WidthAuthorPictureModifier,
|
||||
) {
|
||||
ZappedIcon(
|
||||
modifier = remember { Modifier.size(Size25dp).align(Alignment.TopEnd) },
|
||||
modifier = Modifier.size(Size25dp).align(Alignment.TopEnd),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -353,7 +353,7 @@ fun RenderBoostGallery(
|
||||
modifier = NotificationIconModifierSmaller,
|
||||
) {
|
||||
RepostedIcon(
|
||||
modifier = remember { Modifier.size(Size20dp).align(Alignment.TopEnd) },
|
||||
modifier = Modifier.size(Size20dp).align(Alignment.TopEnd),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -374,7 +374,7 @@ fun RenderBoostGallery(
|
||||
modifier = NotificationIconModifierSmaller,
|
||||
) {
|
||||
RepostedIcon(
|
||||
modifier = remember { Modifier.size(Size20dp).align(Alignment.TopEnd) },
|
||||
modifier = Modifier.size(Size20dp).align(Alignment.TopEnd),
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -1513,7 +1513,7 @@ fun SecondUserInfoRow(
|
||||
verticalAlignment = CenterVertically,
|
||||
modifier = UserNameMaxRowHeight,
|
||||
) {
|
||||
Column(modifier = remember { Modifier.weight(1f) }) {
|
||||
Column(modifier = Modifier.weight(1f)) {
|
||||
if (noteEvent is IForkableEvent && noteEvent.isAFork()) {
|
||||
ShowForkInformation(noteEvent, Modifier, accountViewModel, nav)
|
||||
} else {
|
||||
|
||||
@@ -28,7 +28,6 @@ import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
@@ -136,7 +135,7 @@ fun UserComposeNoAction(
|
||||
) {
|
||||
UserPicture(baseUser, Size55dp, accountViewModel = accountViewModel, nav = nav)
|
||||
|
||||
Column(modifier = remember { Modifier.padding(start = 10.dp).weight(1f) }) {
|
||||
Column(modifier = Modifier.padding(start = 10.dp).weight(1f)) {
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
UsernameDisplay(baseUser, accountViewModel = accountViewModel)
|
||||
}
|
||||
|
||||
@@ -29,7 +29,6 @@ import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment.Companion.CenterVertically
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
@@ -75,19 +74,19 @@ fun UserReactionsRow(
|
||||
)
|
||||
}
|
||||
|
||||
Row(verticalAlignment = CenterVertically, modifier = remember { Modifier.weight(1f) }) {
|
||||
Row(verticalAlignment = CenterVertically, modifier = Modifier.weight(1f)) {
|
||||
UserReplyModel(model)
|
||||
}
|
||||
|
||||
Row(verticalAlignment = CenterVertically, modifier = remember { Modifier.weight(1f) }) {
|
||||
Row(verticalAlignment = CenterVertically, modifier = Modifier.weight(1f)) {
|
||||
UserBoostModel(model)
|
||||
}
|
||||
|
||||
Row(verticalAlignment = CenterVertically, modifier = remember { Modifier.weight(1f) }) {
|
||||
Row(verticalAlignment = CenterVertically, modifier = Modifier.weight(1f)) {
|
||||
UserReactionModel(model)
|
||||
}
|
||||
|
||||
Row(verticalAlignment = CenterVertically, modifier = remember { Modifier.weight(1f) }) {
|
||||
Row(verticalAlignment = CenterVertically, modifier = Modifier.weight(1f)) {
|
||||
UserZapModel(model)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,7 +30,6 @@ import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
@@ -78,7 +77,7 @@ fun ZapUserSetCompose(
|
||||
modifier = Size55Modifier,
|
||||
) {
|
||||
ZappedIcon(
|
||||
remember { Modifier.size(Size25dp).align(Alignment.TopEnd) },
|
||||
Modifier.size(Size25dp).align(Alignment.TopEnd),
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -103,7 +102,7 @@ fun ZapUserSetCompose(
|
||||
nav = nav,
|
||||
)
|
||||
|
||||
Column(modifier = remember { Modifier.padding(start = 10.dp).weight(1f) }) {
|
||||
Column(modifier = Modifier.padding(start = 10.dp).weight(1f)) {
|
||||
Row(verticalAlignment = Alignment.CenterVertically) { UsernameDisplay(zapSetCard.user, accountViewModel = accountViewModel) }
|
||||
|
||||
AboutDisplay(zapSetCard.user, accountViewModel)
|
||||
|
||||
+1
-1
@@ -167,7 +167,7 @@ fun LongPublicChatChannelHeader(
|
||||
modifier = Modifier.width(75.dp),
|
||||
)
|
||||
Spacer(DoubleHorzSpacer)
|
||||
NormalTimeAgo(note, remember { Modifier.weight(1f) })
|
||||
NormalTimeAgo(note, Modifier.weight(1f))
|
||||
MoreOptionsButton(note, null, accountViewModel, nav)
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -116,7 +116,7 @@ fun LongLiveActivityChannelHeader(
|
||||
modifier = Modifier.width(75.dp),
|
||||
)
|
||||
Spacer(DoubleHorzSpacer)
|
||||
NormalTimeAgo(note, remember { Modifier.weight(1f) })
|
||||
NormalTimeAgo(note, Modifier.weight(1f))
|
||||
MoreOptionsButton(note, null, accountViewModel, nav)
|
||||
}
|
||||
}
|
||||
|
||||
+1
-2
@@ -30,7 +30,6 @@ import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.vitorpamplona.amethyst.commons.icons.symbols.Icon
|
||||
@@ -57,7 +56,7 @@ fun DisplayReplyingToNote(
|
||||
.animateContentSize(),
|
||||
) {
|
||||
if (replyingNote != null) {
|
||||
Column(remember { Modifier.weight(1f) }) {
|
||||
Column(Modifier.weight(1f)) {
|
||||
ChatroomMessageCompose(
|
||||
baseNote = replyingNote,
|
||||
null,
|
||||
|
||||
+1
-1
@@ -535,7 +535,7 @@ private fun FullBleedNoteCompose(
|
||||
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
Column(
|
||||
remember { Modifier.weight(1f) },
|
||||
Modifier.weight(1f),
|
||||
) {
|
||||
if (noteEvent is IForkableEvent && noteEvent.isAFork()) {
|
||||
ShowForkInformation(noteEvent, Modifier, accountViewModel, nav)
|
||||
|
||||
+1
-1
@@ -79,7 +79,7 @@ fun BookmarksScreen(
|
||||
onZapFeedback: (ZapFeedback) -> Unit = {},
|
||||
) {
|
||||
val relayStatuses by relayManager.relayStatuses.collectAsState()
|
||||
val connectedRelays = remember(relayStatuses) { relayStatuses.keys }
|
||||
val connectedRelays = relayStatuses.keys
|
||||
val scope = rememberCoroutineScope()
|
||||
|
||||
// Tab state
|
||||
|
||||
@@ -280,7 +280,7 @@ fun FeedScreen(
|
||||
val followedUsers by localCache.followedUsers.collectAsState()
|
||||
|
||||
// Available relay URLs — subscribe triggers connection on-demand
|
||||
val allRelayUrls = remember(relayStatuses) { relayStatuses.keys }
|
||||
val allRelayUrls = relayStatuses.keys
|
||||
|
||||
// Feed relays from relay categories (NIP-65 outbox, minus blocked, with fallback)
|
||||
val relayCategories = LocalRelayCategories.current
|
||||
|
||||
+1
-1
@@ -115,7 +115,7 @@ fun NotificationsScreen(
|
||||
subscriptionsCoordinator: DesktopRelaySubscriptionsCoordinator? = null,
|
||||
) {
|
||||
val relayStatuses by relayManager.relayStatuses.collectAsState()
|
||||
val connectedRelays = remember(relayStatuses) { relayStatuses.keys }
|
||||
val connectedRelays = relayStatuses.keys
|
||||
val scope = rememberCoroutineScope()
|
||||
val notificationState =
|
||||
remember {
|
||||
|
||||
@@ -183,7 +183,7 @@ fun ReadsScreen(
|
||||
onZapFeedback: (ZapFeedback) -> Unit = {},
|
||||
) {
|
||||
val relayStatuses by relayManager.relayStatuses.collectAsState()
|
||||
val connectedRelays = remember(relayStatuses) { relayStatuses.keys }
|
||||
val connectedRelays = relayStatuses.keys
|
||||
val scope = rememberCoroutineScope()
|
||||
|
||||
val eventState =
|
||||
|
||||
@@ -130,7 +130,7 @@ fun SearchScreen(
|
||||
|
||||
val connectedRelays by relayManager.connectedRelays.collectAsState()
|
||||
val relayStatuses by relayManager.relayStatuses.collectAsState()
|
||||
val allRelayUrls = remember(relayStatuses) { relayStatuses.keys }
|
||||
val allRelayUrls = relayStatuses.keys
|
||||
val relayCategories = LocalRelayCategories.current
|
||||
val searchRelays by relayCategories.searchRelays.collectAsState()
|
||||
val displayText by state.displayText.collectAsState()
|
||||
|
||||
@@ -90,7 +90,7 @@ fun ThreadScreen(
|
||||
onReply: (Event) -> Unit = {},
|
||||
) {
|
||||
val relayStatuses by relayManager.relayStatuses.collectAsState()
|
||||
val connectedRelays = remember(relayStatuses) { relayStatuses.keys }
|
||||
val connectedRelays = relayStatuses.keys
|
||||
|
||||
// Lightbox state
|
||||
var lightboxState by remember { mutableStateOf<LightboxState?>(null) }
|
||||
|
||||
+1
-1
@@ -122,7 +122,7 @@ fun UserProfileScreen(
|
||||
onZapFeedback: (ZapFeedback) -> Unit = {},
|
||||
) {
|
||||
val relayStatuses by relayManager.relayStatuses.collectAsState()
|
||||
val connectedRelays = remember(relayStatuses) { relayStatuses.keys }
|
||||
val connectedRelays = relayStatuses.keys
|
||||
|
||||
// User metadata — seed from cache so returning to profile is instant
|
||||
val cachedUser = remember(pubKeyHex) { localCache.getUserIfExists(pubKeyHex) }
|
||||
|
||||
+1
-1
@@ -78,7 +78,7 @@ fun NewDmDialog(
|
||||
val relaySearchResults by searchState.relaySearchResults.collectAsState()
|
||||
val isSearchingRelays by searchState.isSearchingRelays.collectAsState()
|
||||
val relayStatuses by relayManager.relayStatuses.collectAsState()
|
||||
val connectedRelays = remember(relayStatuses) { relayStatuses.keys }
|
||||
val connectedRelays = relayStatuses.keys
|
||||
val focusRequester = remember { FocusRequester() }
|
||||
|
||||
// NIP-50 relay search when local cache has few/no results
|
||||
|
||||
Reference in New Issue
Block a user