Balloon
Balloon copied to clipboard
Performance impact when using in LazyColumn
Please complete the following information:
- Library Version [1.6.1]
- Compose BoM [2023.10.01]
Describe the Bug:
When you're building a large screen and use LazyColumn
with multiple Balloon
you'll get performance impact - slight freeze during scrolling even on release build
Expected Behavior:
No performance reduction
Example
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
MyApplicationTheme {
// A surface container using the 'background' color from the theme
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
val builder = rememberBalloonBuilder {
setArrowSize(10)
setArrowPosition(0.5f)
setArrowPositionRules(ArrowPositionRules.ALIGN_ANCHOR)
setWidth(BalloonSizeSpec.WRAP)
setHeight(BalloonSizeSpec.WRAP)
setPadding(12)
setMarginHorizontal(12)
setCornerRadius(8f)
setBackgroundColor(Color(0xFF673AB7))
setBalloonAnimation(BalloonAnimation.ELASTIC)
}
LazyColumn(modifier = Modifier.fillMaxSize()) {
item(key = 1) { Item(builder = builder) }
item(key = 2) { Item(builder = builder) }
item(key = 3) { Section(color = Color.Blue, text = "Section #1") }
item(key = 4) { Section(color = Color.Magenta, text = "Section #2") }
item(key = 5) { Section(color = Color.Black, text = "Section #3") }
item(key = 6) { Section(color = Color.Gray, text = "Section #4") }
}
}
}
}
}
@Composable
private fun Section(color: Color, text: String) {
Box(
modifier = Modifier
.fillMaxWidth()
.height(400.dp)
.background(color = color)
) {
Text(
modifier = Modifier.align(Alignment.Center),
text = text,
color = Color.White
)
}
}
@Composable
private fun Item(builder: Balloon.Builder) {
Row(modifier = Modifier.fillMaxWidth()) {
Spacer(modifier = Modifier.width(16.dp))
Tooltip(builder = builder)
Spacer(modifier = Modifier.weight(1F))
Tooltip(builder = builder)
Spacer(modifier = Modifier.weight(1F))
Tooltip(builder = builder)
Spacer(modifier = Modifier.width(16.dp))
}
}
@Composable
private fun Tooltip(builder: Balloon.Builder) {
Box {
Balloon(
modifier = Modifier.align(Alignment.Center),
builder = builder,
balloonContent = {
Text(text = "Tooltip text", color = Color.White)
}
) { balloonWindow ->
Button(
onClick = {
balloonWindow.showAlignBottom()
}
) {
Text(text = "Show")
}
}
}
}
}
Hey @OlehHaidaienko, sorry for the late response. I'm wondering if this still happens with the latest version 1.6.3. Thanks!
@skydoves Hi, unfortunately still reproducible on 1.6.3. Please check the screen recordings.
On the second screen recording, I just commented Balloon
composable function
Tooltip enabled.webm
Tooltip disabled.webm
Hi @skydoves, I've been also looking into some performance issues with Balloon tooltips in Compose, and one thing I noticed is that the Balloon
composable takes a com.skydoves.balloon.Balloon.Builder
argument which is considered unstable by the Compose compiler. See example report from the app I am working on:
restartable fun WithTooltip(
stable showTooltipEffectKey: String
unstable balloonBuilder: Builder
stable balloonContent: Function2<Composer, Int, Unit>
stable onTooltipShown: Function0<Unit>
stable content: Function2<Composer, Int, Unit>
)
(generated using these instructions)
I am not sure how the builder is used internally, so I can't give any advice on how to solve this (e.g. if annotating with @Stable
would help). Also I haven't done any profiling beyond this, so I can't tell for sure if this is the source of the performance issue, but I suspect that making the composable stable would help either way.
Hey @eduardb, I don't think it's directly related to the stable marker, but I just released a snapshot version (1.6.5-SNAPSHOT), which annotates the Balloon.Builder
as stable. You can import the snapshot version following this instruction: https://github.com/skydoves/Balloon?tab=readme-ov-file#snapshot
I confirm also have the same problem, and it's actually pretty bad. I have a LazyColumn in my app and each item has two balloons for tooltips and scrolling even in release build gets SOO laggy. Once I remove the balloons - everything gets back to perfectly smooth scrolling. I guess maybe thats because of creating of the builder for each item even though it's remembered...I wanna try and see if I can create the builder just once for the entire app and provide it in items through the LocalComposition... But yeah the problem is quiet severe and not obvious, It took me a few hours to realize it's because of the balloons
UPD: Moving the creation of builder outside of each lazy item didnt help (I moved it on the screen level composition and provided down the item composable - just for a quick test if this will even work) The snapshot version didn't fix the problem either
Hi,
I observed the same behavior in my application, updating to last version (1.6.5) didn't improve the performance issue. Have you eventually come up with a workaround @OlehHaidaienko ?
@JeremyThivet Hi, for this case, I created a simple tooltip implementation based on Popup
composable function