perf(note types): second pass — fix more missing remember keys
Follow-up to the first perf pass. Same goal: cut allocation cost for
note rows that scroll inside LazyColumn feeds.
- AppDefinition: key the `remember { tags.toImmutableListOfLists() }`
block by `note` so it actually invalidates when the note changes
- NIP90ContentDiscoveryResponse: drop the `remember(note) {
Modifier.fillMaxWidth() }` wrapper — `Modifier.fillMaxWidth()` is a
constant call
- PeopleList: key the `derivedStateOf` for `name` by `noteEvent`, and
switch `LaunchedEffect(Unit)` to `LaunchedEffect(noteEvent)` so the
participants reload when the underlying event changes
- PinList: replace `val pins by remember { mutableStateOf(noteEvent
.pinnedEvents()) }` with `val pins = remember(noteEvent) { … }` —
the `mutableStateOf` wrapper was unnecessary and the missing key
meant `pins` could go stale on event updates
- LongForm: return the `topics` list as `ImmutableList` so Compose
treats it as a stable parameter to the consuming `forEach`
- RelayList: drop the `mutableStateOf(RelayListCard(…))` wrap inside
4 `remember` blocks (DisplayRelaySet, DisplayNIP65RelayList write/
read, DisplayDMRelayList) — the value never changes after creation;
also key by `noteEvent` rather than `baseNote`, and cache
`noteEvent.description()`
- Torrent: wrap `noteEvent.title() + totalSizeBytes()`, content
comparison and `files().toImmutableList()` in `remember(noteEvent)`
so they don't recompute and reallocate on every recomposition
This commit is contained in:
@@ -216,7 +216,7 @@ fun RenderAppDefinition(
|
||||
CreateTextWithEmoji(
|
||||
text = it,
|
||||
tags =
|
||||
remember {
|
||||
remember(note) {
|
||||
(note.event?.tags ?: emptyArray()).toImmutableListOfLists()
|
||||
},
|
||||
fontWeight = FontWeight.Bold,
|
||||
|
||||
@@ -64,6 +64,7 @@ import com.vitorpamplona.amethyst.ui.theme.Size5dp
|
||||
import com.vitorpamplona.amethyst.ui.theme.grayText
|
||||
import com.vitorpamplona.amethyst.ui.theme.replyModifier
|
||||
import com.vitorpamplona.quartz.nip23LongContent.LongTextNoteEvent
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
|
||||
private const val WORDS_PER_MINUTE = 225
|
||||
private val COVER_ASPECT_RATIO = 16f / 9f
|
||||
@@ -92,7 +93,14 @@ fun LongFormHeader(
|
||||
remember(noteEvent) {
|
||||
noteEvent.summary()?.ifBlank { null } ?: noteEvent.content.take(200).ifBlank { null }
|
||||
}
|
||||
val topics = remember(noteEvent) { noteEvent.topics().distinct().take(3) }
|
||||
val topics =
|
||||
remember(noteEvent) {
|
||||
noteEvent
|
||||
.topics()
|
||||
.distinct()
|
||||
.take(3)
|
||||
.toImmutableList()
|
||||
}
|
||||
val readingMinutes = remember(noteEvent) { estimateReadingMinutes(noteEvent.content) }
|
||||
|
||||
Column(MaterialTheme.colorScheme.replyModifier) {
|
||||
|
||||
+1
-2
@@ -54,7 +54,6 @@ fun RenderNIP90ContentDiscoveryResponse(
|
||||
note = note,
|
||||
accountViewModel = accountViewModel,
|
||||
) {
|
||||
val modifier = remember(note) { Modifier.fillMaxWidth() }
|
||||
val tags =
|
||||
remember(note) { note.event?.tags?.toImmutableListOfLists() ?: EmptyTagList }
|
||||
|
||||
@@ -62,7 +61,7 @@ fun RenderNIP90ContentDiscoveryResponse(
|
||||
content = noteEvent.content,
|
||||
canPreview = canPreview && !makeItShort,
|
||||
quotesLeft = quotesLeft,
|
||||
modifier = modifier,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
tags = tags,
|
||||
backgroundColor = backgroundColor,
|
||||
id = note.idHex,
|
||||
|
||||
@@ -81,7 +81,7 @@ fun DisplayPeopleList(
|
||||
members.take(3)
|
||||
}
|
||||
|
||||
val name by remember { derivedStateOf { "#${noteEvent.titleOrName() ?: noteEvent.dTag()}" } }
|
||||
val name by remember(noteEvent) { derivedStateOf { "#${noteEvent.titleOrName() ?: noteEvent.dTag()}" } }
|
||||
|
||||
Text(
|
||||
text = name,
|
||||
@@ -95,7 +95,7 @@ fun DisplayPeopleList(
|
||||
textAlign = TextAlign.Center,
|
||||
)
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
LaunchedEffect(noteEvent) {
|
||||
accountViewModel.loadUsers(noteEvent.taggedUserIds()) {
|
||||
members = it
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ fun RenderPinListEvent(
|
||||
) {
|
||||
val noteEvent = baseNote.event as? PinListEvent ?: return
|
||||
|
||||
val pins by remember { mutableStateOf(noteEvent.pinnedEvents()) }
|
||||
val pins = remember(noteEvent) { noteEvent.pinnedEvents() }
|
||||
|
||||
var expanded by remember { mutableStateOf(false) }
|
||||
|
||||
|
||||
@@ -75,12 +75,10 @@ fun DisplayRelaySet(
|
||||
) {
|
||||
val noteEvent = baseNote.event as? RelaySetEvent ?: return
|
||||
|
||||
val relays by
|
||||
val relays =
|
||||
remember(noteEvent) {
|
||||
mutableStateOf(
|
||||
RelayListCard(
|
||||
noteEvent.relays().toImmutableList(),
|
||||
),
|
||||
RelayListCard(
|
||||
noteEvent.relays().toImmutableList(),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -89,10 +87,12 @@ fun DisplayRelaySet(
|
||||
noteEvent.tags.firstTagValueFor("title", "name") ?: "#${noteEvent.dTag()}"
|
||||
}
|
||||
|
||||
val description = remember(noteEvent) { noteEvent.description() }
|
||||
|
||||
DisplayRelaySet(
|
||||
relays,
|
||||
relayListName,
|
||||
noteEvent.description(),
|
||||
description,
|
||||
backgroundColor,
|
||||
accountViewModel,
|
||||
nav,
|
||||
@@ -108,21 +108,17 @@ fun DisplayNIP65RelayList(
|
||||
) {
|
||||
val noteEvent = baseNote.event as? AdvertisedRelayListEvent ?: return
|
||||
|
||||
val writeRelays by
|
||||
remember(baseNote) {
|
||||
mutableStateOf(
|
||||
RelayListCard(
|
||||
noteEvent.writeRelaysNorm() ?: emptyList(),
|
||||
),
|
||||
val writeRelays =
|
||||
remember(noteEvent) {
|
||||
RelayListCard(
|
||||
noteEvent.writeRelaysNorm() ?: emptyList(),
|
||||
)
|
||||
}
|
||||
|
||||
val readRelays by
|
||||
remember(baseNote) {
|
||||
mutableStateOf(
|
||||
RelayListCard(
|
||||
noteEvent.readRelaysNorm() ?: emptyList(),
|
||||
),
|
||||
val readRelays =
|
||||
remember(noteEvent) {
|
||||
RelayListCard(
|
||||
noteEvent.readRelaysNorm() ?: emptyList(),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -154,12 +150,10 @@ fun DisplayDMRelayList(
|
||||
) {
|
||||
val noteEvent = baseNote.event as? ChatMessageRelayListEvent ?: return
|
||||
|
||||
val relays by
|
||||
remember(baseNote) {
|
||||
mutableStateOf(
|
||||
RelayListCard(
|
||||
noteEvent.relays(),
|
||||
),
|
||||
val relays =
|
||||
remember(noteEvent) {
|
||||
RelayListCard(
|
||||
noteEvent.relays(),
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -153,19 +153,24 @@ fun RenderTorrent(
|
||||
) {
|
||||
val noteEvent = note.event as? TorrentEvent ?: return
|
||||
|
||||
val name = (noteEvent.title() ?: TorrentEvent.ALT_DESCRIPTION)
|
||||
val size = " (" + countToHumanReadableBytes(noteEvent.totalSizeBytes()) + ")"
|
||||
|
||||
val description =
|
||||
if (noteEvent.content != name) {
|
||||
noteEvent.content
|
||||
} else {
|
||||
null
|
||||
val title =
|
||||
remember(noteEvent) {
|
||||
val name = noteEvent.title() ?: TorrentEvent.ALT_DESCRIPTION
|
||||
val size = " (" + countToHumanReadableBytes(noteEvent.totalSizeBytes()) + ")"
|
||||
name + size
|
||||
}
|
||||
|
||||
val description =
|
||||
remember(noteEvent) {
|
||||
val name = noteEvent.title() ?: TorrentEvent.ALT_DESCRIPTION
|
||||
if (noteEvent.content != name) noteEvent.content else null
|
||||
}
|
||||
|
||||
val files = remember(noteEvent) { noteEvent.files().toImmutableList() }
|
||||
|
||||
DisplayFileList(
|
||||
noteEvent.files().toImmutableList(),
|
||||
name + size,
|
||||
files,
|
||||
title,
|
||||
description,
|
||||
noteEvent::toMagnetLink,
|
||||
backgroundColor,
|
||||
|
||||
Reference in New Issue
Block a user