I'm noticing that Compose Desktop feels a little s...
# compose-desktop
d
I'm noticing that Compose Desktop feels a little sluggish, even with a bare bones UI. Any suggestions on improving performance?
s
Hey! To save a few back-and-forth messages, it’d be super helpful if you could provide the following: • Operating system you’re using; • Compose for Desktop version; • Code sample or minimal project that reproduces the issue (if possible); What exactly feels slow: • Is it slow to launch? • Scrolling lists laggy? • Animations choppy? • Anything else specific? Thanks!
thank you color 1
d
Scrolling and resizing are laggy. I can throw up a sample repo in a little bit, but I’m using the latest version of everything.
OS info:
Project also includes a "SwingMain.kt" is not choppy for scrolling or resizing.
👀 1
a
Not that it justifies the sluggishness, but that’s a fairly old computer, with an integrated GPU.
I have a MacBook Air from about that year, though, so I can investigate.
s
If old Swing can draw fast enough, then maybe the problem isn’t in the hardware?
a
Old Swing was running fast on computers from 2005, so it’s no contest.
s
What I mean is, the goal of a UI library is to put pixels on the screen fast enough. If one library produces the result quickly, but another produces the exact same result much, much slower, then I’d assume the problem isn’t with the hardware.
a
Hardware is never “the problem”, but more modern software typically relies on more modern hardware. Developer resources are limited, so while in 2005 it’s worthwhile to spend them to optimize software to run on 2005 hardware, in 2025, it’s not.
👍🏻 1
s
I understand that modern software often requires modern hardware capabilities, but Compose isn’t doing anything that older, “legacy” UI libraries didn’t already handle. It’s just putting text and colored rectangles on the screen. It’s not Unreal Engine 5 or anything like that. So I don’t quite understand why it would require more advanced hardware or why the performance bar is set higher. 🙂
a
I think I already explained
K 1
d
Please do investigate. The GPU is decent enough, and most other frameworks don't suffer from this. I suspect its a different kind of bottleneck that might be addressable.
The GPU is also an AMD Radaen Pro 560X, which should be more than enough to handle a scroll pane.
t
@Daniel Pitts did you try using LazyColumn? Create immutable list of 100 elements (or make sure to instruct compose to treat the List as immutable). Use LazyColumn and pass the list to an "items" type.
d
@Tomislav Mladenov Here is the thing: Resizing the window feels sluggish even when the only thing rendered is an empty
Scaffold
t
I see, I would suggest to change hardware or technology
d
I've actually narrowed it down to the ComposePanel causing the stuttering:
Copy code
import androidx.compose.ui.awt.*
import java.awt.EventQueue.*
import javax.swing.*

fun main() {
    invokeLater {
        JFrame().apply {
            title = "Normal JFrame"
            defaultCloseOperation = JFrame.DISPOSE_ON_CLOSE
            setSize(800, 600)
            contentPane = ComposePanel()
            isVisible = true
        }
    }
}
For this one, if I comment out
contentPane = ComposePanel()
, it resizes smoothly. Otherwise it stutters. It seems likely that something in the either the ComposeContainer or in the Skia code itself is blocking the EDT thread when it shouldn't.
👀 1
I've narrowed it down even further. The paint() method in
SkiaLayer
takes 16ms while resizing, which indicates its waiting for a vsync. (16ms = ~60hz). The thing is that AWT already waits for vsync, so its basically wasting a frame.
a
You can set skiko.rendering.macos.waitForPreviousFrameVsyncOnRedrawImmediately=false to disable that
d
That solved it!
Seems like waiting for vSync shouldn't ever happen on the EDT. This would cause problems on any hardware, so its not just an issue because I'm on an older laptop.
a
I’ll take a look at it on Monday, see if it’s really needed there.
👍 1
d
The in-code comment is:
Copy code
// Wait for vsync because:
// - macOS drops the second/next drawables if they are sent in the same vsync
// - it makes frames consistent and limits FPS
Sounds like maybe this was a work-around for some other bug? Anyway, thanks for taking a look!
a
It’s not a bug, that’s how Metal works. But maybe it’s not needed when called from paint
d