element-hq / element-hq/element-x-android

Recomposition & State issues - nothing gets `remember { ... }`'ed

Ouverte
#262 6 commentaires 0 réactions 0 personnes assignées Voir sur GitHub
A-Performance O-Uncommon S-Minor T-Defect
Langage dominant
Kotlin
Étoiles
2.4k
Forks
624
Merge moyen
1 j 14 h
PR mergées (30 j)
149

Description

### Steps to reproduce

Preface: I don't know much Android-development at all and I have minimal Kotlin experience.

# Irrelevant apropo
I ran into this issue, because I'm starting to implement a rudimentary syntax highlighting engine, similar to the one we can see on the normal web app.

The syntax highlighting stuff is trivial (and I do think the android app should mimick the browser/desktop version), whether one should handroll per language, or do some regex stuff - either way, reducing 3rd party dependencies is always a good thing. Always.

The thing is though, running syntax highlighting on a message should only be done once. So how would I go about doing this? Using `remember { ... }` right? Which brings me to:

### Outcome

# Actual issue
Every time recomposition happens, the `remember { }` stuff never actually remembers anything. This got me thinking; I have very little experience in the JVM/Android platform, so I might not be doing it right, at all.

But then I set some breakpoints, and it seems, this functionality is not working as expected _anywhere_.

For instance, in the [`TimelineItemTextView`](https://github.com/vector-im/element-x-android/blob/develop/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemTextView.kt#L63) composable, there's a `remember(content.body)` - and it gets called _every time_ recomposition happens, making it completely unnecessary to have it in a remember block, no?

In other words, the data never changes, yet all these styles need to be applied every time, doing costly operations, over, and over, and over again.

Now, I'm not well-versed in Compose (or Kotlin for that matter) but this seems to be a design flaw, right? The client has the data, yet it has to go through all the hoops of parsing it into a document etc applying styles, etc.

The culprit seems to be [`TimelineView`](https://github.com/vector-im/element-x-android/blob/develop/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineView.kt#L105-L110) which refires every recomposition and thus forces _everything_ below it to update as well. Other `remember` calls actually remembers their state, but everything "below" this point, remember seem to not work at all.

Now, it makes sense that recomposition should happen, when scrolling, but every subsequent child in that "`Timeline` " has their operations applied fully, not just their positions or layout in the UI, but as previously show, the `linkify` stuff as well (and in my case - the reparsing of the syntax + applying colors on "code blocks"), the traversing of already parsed html, etc. The data of all the subcomponents should only be calculated once, it seems to me, only the UI should care.

Is this the intended design? What can be done about it? If anyone has ideas on how to solve it?

### Your phone model

Pixel 7 (Emulator)

### Operating system version

Doesn't matter.

### Application version and app store

develop branch

### Homeserver

matrix.org

### Will you send logs?

No

### Are you willing to provide a PR?

Yes

Guide de contribution

Ouvrir le guide de contribution

Évaluation

Cette issue n'a pas encore été évaluée.

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.