compose-multiplatform
compose-multiplatform copied to clipboard
Text component with UTF-8 emoji text draws very slow (takes seconds)
Describe the bug
i made an emoji popup:
LazyColumn(
modifier = Modifier.fillMaxSize().padding(start = 1.dp, end = 10.dp),
verticalArrangement = Arrangement.spacedBy(5.dp),
state = listState,
) {
items(items = emojis_cat_0_gropued) {
Row(modifier = Modifier.fillMaxWidth().height(40.dp)) {
for (k in 0..(it.size - 1))
{
IconButton(modifier = Modifier.width(40.dp).height(40.dp),
onClick = { inputText = inputText + it[k] }) {
Text(text = it[k], fontSize = 30.sp, maxLines = 1)
}
}
}
}
}
sadly its unbearably slow to scroll. if i replace the emoji strings with a normal string like "XX" its super fast. what is going on here? its seems just drawing unicode emoji symbols is unbearably slow
Affected platforms Select one of the platforms below:
- Desktop
Versions
- Kotlin version*: 1.9.22
- Compose Multiplatform version*: 1.5.12, 1.5.11, 1.6.0-dev1383
- OS version(s)* (required for Desktop and iOS issues): linux ubuntu 22.04 (but on windows i think also)
- OS architecture (x86 or arm64): x86 64bit
- JDK (for desktop issues): 17 and 21
Screenshots If applicable, add screenshots to help explain your problem.
emoji popup showing on linux, macos and windows in the lower right corner. when scrolling the box to show more emoji its stuck for 1 second or longer. when replacing all the emoji text with plain "XX" scrolling is super fast like it should be
Hello! I can't compile this code as is. Could you please create a minimal reproducible example?
fun App()
{
var al: ArrayList<String> = arrayListOf(
"๐","๐","๐","๐","๐","๐
",
"๐คฃ","๐","๐","๐","๐ซ ","๐",
"๐","๐","๐ฅฐ","๐","๐คฉ","๐",
"๐","โบ๏ธ","๐","๐","๐ฅฒ","๐",
"๐","๐","๐คช","๐","๐ค","๐ค",
"๐คญ","๐ซข","๐ซฃ","๐คซ","๐ค","๐ซก",
"๐ค","๐คจ","๐","๐","๐ถ","๐ซฅ",
"๐ถโ๐ซ๏ธ","๐","๐","๐","๐ฌ","๐ฎโ๐จ",
"๐คฅ","๐ซจ","๐","๐","๐ช","๐คค",
"๐ด","๐ท","๐ค","๐ค","๐คข","๐คฎ",
"๐คง","๐ฅต","๐ฅถ","๐ฅด","๐ต","๐ตโ๐ซ",
"๐คฏ","๐ค ","๐ฅณ","๐ฅธ","๐","๐ค",
"๐ง","๐","๐ซค","๐","๐","โน๏ธ",
"๐ฎ","๐ฏ","๐ฒ","๐ณ","๐ฅบ","๐ฅน",
"๐ฆ","๐ง","๐จ","๐ฐ","๐ฅ","๐ข",
"๐ญ","๐ฑ","๐","๐ฃ","๐","๐",
"๐ฉ","๐ซ","๐ฅฑ","๐ค","๐ก","๐ ",
"๐คฌ","๐","๐ฟ","๐","โ ๏ธ","๐ฉ",
"๐คก","๐น","๐บ","๐ป","๐ฝ","๐พ",
"๐ค","๐บ","๐ธ","๐น","๐ป","๐ผ",
"๐ฝ","๐","๐ฟ","๐พ","๐","๐",
"๐","๐","๐","๐","๐","๐",
"๐","๐","๐","๐","โฃ๏ธ","๐",
"โค๏ธโ๐ฅ","โค๏ธโ๐ฉน","โค๏ธ","๐ฉท","๐งก","๐",
"๐","๐","๐ฉต","๐","๐ค","๐ค",
"๐ฉถ","๐ค","๐","๐ฏ","๐ข","๐ฅ",
"๐ซ","๐ฆ","๐จ","๐ณ๏ธ","๐ฌ","๐๏ธโ๐จ๏ธ",
"๐จ๏ธ","๐ฏ๏ธ","๐ญ","๐ค","๐","๐ค",
"๐๏ธ","โ","๐","๐ซฑ","๐ซฒ","๐ซณ",
"๐ซด","๐ซท","๐ซธ","๐","๐ค","๐ค",
"โ๏ธ","๐ค","๐ซฐ","๐ค","๐ค","๐ค",
"๐","๐","๐","๐","๐","โ๏ธ",
"๐ซต","๐","๐","โ","๐","๐ค",
"๐ค","๐","๐","๐ซถ","๐","๐คฒ",
"๐ค","๐","โ๏ธ","๐
","๐คณ","๐ช",
"๐ฆพ","๐ฆฟ","๐ฆต","๐ฆถ","๐","๐ฆป",
"๐","๐ง ","๐ซ","๐ซ","๐ฆท","๐ฆด",
"๐","๐๏ธ","๐
","๐","๐ซฆ","๐ถ",
"๐ง","๐ฆ","๐ง","๐ง","๐ฑ","๐จ",
"๐ง","๐งโโ๏ธ","๐งโโ๏ธ","๐จโ๐ฆฐ","๐จโ๐ฆฑ","๐จโ๐ฆณ",
"๐จโ๐ฆฒ","๐ฉ","๐ฉโ๐ฆฐ","๐งโ๐ฆฐ","๐ฉโ๐ฆฑ","๐งโ๐ฆฑ",
"๐ฉโ๐ฆณ","๐งโ๐ฆณ","๐ฉโ๐ฆฒ","๐งโ๐ฆฒ","๐ฑโโ๏ธ","๐ฑโโ๏ธ",
"๐ง","๐ด","๐ต","๐","๐โโ๏ธ","๐โโ๏ธ",
"๐","๐โโ๏ธ","๐โโ๏ธ","๐
","๐
โโ๏ธ","๐
โโ๏ธ",
"๐","๐โโ๏ธ","๐โโ๏ธ","๐","๐โโ๏ธ","๐โโ๏ธ",
"๐","๐โโ๏ธ","๐โโ๏ธ","๐ง","๐งโโ๏ธ","๐งโโ๏ธ",
"๐","๐โโ๏ธ","๐โโ๏ธ","๐คฆ","๐คฆโโ๏ธ","๐คฆโโ๏ธ",
"๐คท","๐คทโโ๏ธ","๐คทโโ๏ธ","๐งโโ๏ธ","๐จโโ๏ธ","๐ฉโโ๏ธ",
"๐งโ๐","๐จโ๐","๐ฉโ๐","๐งโ๐ซ","๐จโ๐ซ","๐ฉโ๐ซ",
"๐งโโ๏ธ","๐จโโ๏ธ","๐ฉโโ๏ธ","๐งโ๐พ","๐จโ๐พ","๐ฉโ๐พ",
"๐งโ๐ณ","๐จโ๐ณ","๐ฉโ๐ณ","๐งโ๐ง","๐จโ๐ง","๐ฉโ๐ง",
"๐งโ๐ญ","๐จโ๐ญ","๐ฉโ๐ญ","๐งโ๐ผ","๐จโ๐ผ","๐ฉโ๐ผ",
"๐งโ๐ฌ","๐จโ๐ฌ","๐ฉโ๐ฌ","๐งโ๐ป","๐จโ๐ป","๐ฉโ๐ป",
"๐งโ๐ค","๐จโ๐ค","๐ฉโ๐ค","๐งโ๐จ","๐จโ๐จ","๐ฉโ๐จ",
"๐งโโ๏ธ","๐จโโ๏ธ","๐ฉโโ๏ธ","๐งโ๐","๐จโ๐","๐ฉโ๐")
class EmojiStrAndName
{
var char: String = ""
var name: String = ""
}
var emojis_cat_all_gropued: java.util.ArrayList<java.util.ArrayList<java.util.ArrayList<EmojiStrAndName>>> = java.util.ArrayList()
val emojis_cat_gropued: java.util.ArrayList<java.util.ArrayList<EmojiStrAndName>> = java.util.ArrayList()
val emojis_per_row = 6
for (i in 0..((al.size - 1) / emojis_per_row))
{
val pos = i * emojis_per_row
val e: java.util.ArrayList<EmojiStrAndName> = java.util.ArrayList()
for (j in 0..(emojis_per_row - 1))
{
val em = EmojiStrAndName()
try
{
em.char = al[pos + j]
em.name = ""
}
catch(_: Exception)
{
}
try
{
em.name = "??"
} catch (_: java.lang.Exception)
{
}
e.add(em)
}
emojis_cat_gropued.add(e)
}
emojis_cat_all_gropued.add(emojis_cat_gropued)
Column(Modifier.fillMaxSize().background(Color.White)) {
val listState = rememberLazyListState()
Box(Modifier.fillMaxSize()) {
LazyColumn(
modifier = Modifier.fillMaxSize().padding(start = 1.dp, end = 10.dp),
verticalArrangement = Arrangement.spacedBy(5.dp),
state = listState,
) {
items(items = emojis_cat_all_gropued.get(0)) {
Row(modifier = Modifier.fillMaxWidth().height(40.dp)) {
println("size="+ it.size)
for (k in 0..(it.size - 1))
{
val emojistr = it[k].char
IconButton(modifier = Modifier.width(40.dp).height(40.dp),
onClick = {}) {
Text(text = emojistr, color = Color.Black, fontSize = 30.sp, maxLines = 1)
}
}
}
}
}
VerticalScrollbar(
adapter = rememberScrollbarAdapter(listState),
modifier = Modifier.fillMaxHeight().align(Alignment.CenterEnd).width(10.dp)
)
}
}
}
fun main() = application {
Window(onCloseRequest = ::exitApplication) {
App()
}
}
@mazunin-v-jb this code shows that when you drag the scrollbar things totally stop and block. you can not scroll smoothly
with this workaround it is a bit better, but still not great:
for (k in 0..(it.size - 1))
{
val emojistr = it[k].char
val placeholder = "?"
var curtext by remember { mutableStateOf(placeholder) }
val scope = rememberCoroutineScope()
IconButton(modifier = Modifier.width(40.dp).height(40.dp),
onClick = {}) {
Text(text = curtext, color = Color.Black, fontSize = 30.sp, maxLines = 1)
scope.launch {
delay(150)
curtext = emojistr
}
}
}