perf(RichTextViewer): share isMarkdown decision via CachedRichTextParser
The markdown check is purely a function of `content`, but it was a top-level function in RichTextViewer.kt — every distinct instance of the same content (e.g. a quoted note rendered inside its quoter, or the same viral note shown multiple places in a feed) re-scanned the string. Move the decision into `CachedRichTextParser` with its own small LRU keyed on content.hashCode(). Composables still wrap the call in `remember(content)` so recompositions skip even the LRU lookup.
This commit is contained in:
@@ -28,6 +28,7 @@ import com.vitorpamplona.amethyst.commons.richtext.UrlParser
|
||||
|
||||
object CachedRichTextParser {
|
||||
private val richTextCache = LruCache<Int, RichTextViewerState>(50)
|
||||
private val isMarkdownCache = LruCache<Int, Boolean>(200)
|
||||
|
||||
private fun hashCodeCache(
|
||||
content: String,
|
||||
@@ -69,6 +70,25 @@ object CachedRichTextParser {
|
||||
newUrls
|
||||
}
|
||||
}
|
||||
|
||||
// Shared across every RichTextViewer instance so that the same content quoted in multiple
|
||||
// notes only pays for the scan once. The decision is purely a function of `content`.
|
||||
fun isMarkdown(content: String): Boolean {
|
||||
val key = content.hashCode()
|
||||
isMarkdownCache[key]?.let { return it }
|
||||
val result = computeIsMarkdown(content)
|
||||
isMarkdownCache.put(key, result)
|
||||
return result
|
||||
}
|
||||
|
||||
private fun computeIsMarkdown(content: String): Boolean =
|
||||
content.startsWith("> ") ||
|
||||
content.startsWith("# ") ||
|
||||
content.contains("##") ||
|
||||
content.contains("__") ||
|
||||
content.contains("**") ||
|
||||
content.contains("```") ||
|
||||
content.contains("](")
|
||||
}
|
||||
|
||||
object CachedUrlParser {
|
||||
|
||||
@@ -122,15 +122,6 @@ import com.vitorpamplona.quartz.nipB7Blossom.BlossomUri
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
fun isMarkdown(content: String): Boolean =
|
||||
content.startsWith("> ") ||
|
||||
content.startsWith("# ") ||
|
||||
content.contains("##") ||
|
||||
content.contains("__") ||
|
||||
content.contains("**") ||
|
||||
content.contains("```") ||
|
||||
content.contains("](")
|
||||
|
||||
@Composable
|
||||
fun RichTextViewer(
|
||||
content: String,
|
||||
@@ -145,7 +136,7 @@ fun RichTextViewer(
|
||||
nav: INav,
|
||||
) {
|
||||
Column(modifier = modifier) {
|
||||
if (remember(content) { isMarkdown(content) }) {
|
||||
if (remember(content) { CachedRichTextParser.isMarkdown(content) }) {
|
||||
RenderContentAsMarkdown(content, tags, canPreview, quotesLeft, backgroundColor, callbackUri, accountViewModel, nav)
|
||||
} else {
|
||||
RenderRegular(content, tags, canPreview, quotesLeft, backgroundColor, callbackUri, authorPubKey, accountViewModel, nav)
|
||||
|
||||
Reference in New Issue
Block a user