`ScalingLazyColumn` is incredibly, mind blowingly,...
# compose-wear
l
ScalingLazyColumn
is incredibly, mind blowingly, fascinatingly… extremely laggy, even in release builds… 😕 You don't even get 10fps! How is that possible? I tested on the Pixel Watch and the Samsung Galaxy Watch 4. Is Google using these in their apps with some tricks, or is Google using only View APIs? Here's my code:
Copy code
import androidx.wear.compose.foundation.CurvedLayout
import androidx.wear.compose.material.AutoCenteringParams
import androidx.wear.compose.material.Icon
import androidx.wear.compose.material.ScalingLazyColumn
import androidx.wear.compose.material.Text
import androidx.wear.compose.material.ToggleChip
import androidx.wear.compose.material.ToggleChipDefaults
import androidx.wear.compose.material.curvedText
import androidx.wear.compose.material.rememberScalingLazyListState


@Composable
fun SomeScreenContent() {
    ScalingLazyColumn(
        Modifier.fillMaxSize(),
        state = listSate,
        autoCentering = AutoCenteringParams(itemIndex = 0),
    ) {
        items(20) {
            ToggleChip(
                checked = false,
                onCheckedChange = { isChecked -> },
                label = {
                    Text("Some setting")
                },
                toggleControl = {
                    Icon(
                        imageVector = ToggleChipDefaults.switchIcon(checked = false),
                        contentDescription = "setting disabled"
                    )
                }
            )
        }
    }
}
y
I'm using it with artwork images in a media apps and don't see anything like that. Also my todo app has toggles and nothing like that. On GW4/5, PW. So something else going on.
l
Are you using a baseline profile?
y
Is there anything else to that app? Or just a single screen?
Yep. Using baseline profiles. But that only helps with play store installs unless you run those manual steps
And you get baseline profiles for Wear compose for free anyway
l
It's also a Watch Face, but even when it's not the Watch Face and I open this in the MainActivity, and it's extremely laggy after first install
Not just after first install actually
y
Interesting, I wonder if that's relevant. Affects profile installation? But your video is terrible even without baseline profiles
l
Disabled all other components in the manifest by commenting, and I still get this performance level on both watches
b
Reminds me of previous issues I had, albeit on an old device...
y
On Tuesday or so I can drop that example into a macrobenchmark and test the scroll speed. Also with jankstats.
l
Should I hope to find a solution for these performance issues on Wear Compose? Betting on this horse feels pretty risky now, and I'm still quite good with Views in Kotlin…
y
I don't think we've found a performance issue that hasn't had a reasonable fix. So yes, but you are not the only one to have issues with something that looks reasonable.
I'd encourage most apps to use wear material which means wear compose.
l
I'm going to try using
WearableRecyclerView
and putting `ComposeView`s inside it. Worked well in a phone app at my previous job where I needed insert/removal animations
y
That sounds like a lot of overhead. I'd suggest having something like macrobenchmark to show the performance difference when making those decisions. But if I get to it on Tuesday we can get a baseline set of numbers with SLC
l
SLC?
Oh,
ScalingLazyColumn
Could the minSdk affect it? I wanted to support API 25 so I can also run my app on my Huawei Watch which despite huge screen burn it, still works, and is my favorite form factor of all the other watches I have/had.
y
Not sure, I hope not, at least on a 30 device. If so, file a bug.
l
BTW, it looks like it'll be impossible to actually support API 25 without coming back to the old Watch Face APIs, but for other reasons, that's something I'm considering (including watch face composition APIs that allow seconds hand in ambient).
k
@louiscad Can you try to apply baseline profiles manually to see if this makes a difference: https://developer.android.com/training/wearables/compose/performance#commands ?
Also I wonder if you will get jank issues on your watch running the compose sample (https://github.com/android/wear-os-samples/tree/main/ComposeAdvanced)? If you have time to try that
I doubt it’s related to API level 25 (though for apps, not watch faces). We have a few apps using such minSDK and they don’t have performance issues
t
This is really surprising to me. I am using
ScalingLazyColumn
in production and it works flawlessly. On my Watch4 there are no performance issues at all when scrolling. Also the list is much more advanced than your example. I am using R8, but apart from that not really anything special.
Min sdk 25 for me, and 100% (wear) compose
l
For the command about baseline profiles, I get arm:
[status=verify] [reason=boot]
blob thinking fast
About the second command:
adb shell cmd package bg-dexopt-job
it takes a lot more than 40 seconds on the Pixel Watch, it's been 3 minutes and counting 🤔
After running the command just above, I now get
[status=speed-profile] [reason=bg-dexopt]
, but it's still super laggy 😭
All the build types are laggy. debug, staging, release. I'll try the latest ComposeAdvanced repo soon
k
hm, that’s odd 😕 Have you ever rebooted this pixel watch? Are other apps installed from play store laggy too? You can try Todoist, it is the one built with Compose for Wear
l
Ah yes, the welcome screen of Todoist is super laggy
High contrast with everywhere else in the system apps/menus.
And yes, I did reboot the watch today
Todoist can't scroll 4 items smoothly…
y
Just tried todoist fresh from playstore and it's silky smooth
l
Which watch?
y
Pixelwatch
l
There's something very weird happening.
Pixel Watch too, super laggy
Here it is on my side.
k
I also don’t have issues with Todoist on PW, thought my device is slightly different from consumer version. @louiscad what build number is on your watch?
l
BTW, the "Take screenshot" thing is very crappy in the Pixel Watch app. You get a phone notification where you have to "send" it straightaway, and as you scroll, it lags just like the Wear OS app is doing, and icons get shuffled mid-scroll. Why not just save screenshots by default, and let us share only if we want?
If I didn't have the Solid Explorer app, I'd have no way to keep the screenshot around without sending it somewhere first.
So, build number: RWD9.220429.053.G1
Looks like there's something very weird happening with profiles. Todoist is smooth on my Samsung Galaxy Watch 4, unlike on my Pixel Watch, still, apps I deploy with Wear Compose are super laggy on both devices.
I'll be Pixel Watch free for 2 weeks as I'll send this black one to someone in Sweden and will get a silver/gray one when I'm back from a trip. I'll still be able to test things on my Samsung GW4 and my Ticwatch E3.
Current ComposeAdvanced, installed with the
installRelease
Gradle task. Not smooth most of the time.
Same as just above on Samsung Galaxy Watch 4
I just tested with a
WearableRecyclerView
embedding `ComposeView`s, using the latest versions of everything to get the latest performance improvements… I now have a comparison where the app auto-switches between
ScalingLazyColumn
and `ScalingLazyColumnWithRecyclerView`… You'll the thing getting less janky over the scrolls, with one that gets there quicker… We have a teal-ish background for one, and a green-ish background for the other one. Can you guess which is which from that video?
j
@Steve Bower [G] in case you have any thing to contribute on why Louis might be seeing issues
s
This is very odd, the jank in the videos Louis has posted look worse than I'm seeing even with a debug build on a Pixel Watch. Going back to the usual setup questions, please check the tips here: https://developer.android.com/training/wearables/compose/performance such as being sure to set *minify*Enabled true and shrinkResources true in the build.gradle file, and generate a release APK for testing. The command to apply baseline profiles looks correct (adb shell cmd package bg-dexopt-job) but note that has no effect for debug builds.
I created a fresh build of ComposeAdvanced and recorded this video on the Pixel Watch - it looks smooth to me. This is a release build with minifyEnabled and shrinkResources - installed with adb install, launched the app, then ran adb shell cmd package bg-dexopt-job.
l
Of course I have minify and shrinkResources enabled. Note that I have 3 build types: -debug -staging (minified) -release I usually test performance with staging as my goal is to have release be updated from the Play Store only. I tried the release variant anyway (with incompatible signature, so need to uninstall afterwards), and the results looked similar.
If you need, I can share my project to your GitHub handles so you can try for yourself.
j
Can do Louis. What puzzles me though is why you are seeing performance issues with Todoist as well - is that on multiple devices? Something weird is happening for you to see such different performance - be good to help you get to the bottom of it.
l
That was on 2 Wear OS 3.5 devices I tested on: Pixel Watch and Samsung Galaxy Watch 4. I can try on my Ticwatch E3 as well. Shall I? My Huawei Watch is unfortunately not compatible… or the app isn't compatible with it I should say?
To share you the project, I'd need your GitHub handle.
y
So I added this benchmark, loosely based on your example to Compose Advanced. https://github.com/android/wear-os-samples/pull/572/files
Results I got with it
Copy code
ScrollingBenchmark_startup[compilation=None]
frameDurationCpuMs   P50   11.5,   P90   27.5,   P95   42.1,   P99  138.9

ScrollingBenchmark_startup[compilation=BaselineProfile]
frameDurationCpuMs   P50   10.8,   P90   20.9,   P95   31.5,   P99   81.1
Also after installing, results were smooth.
I took the opportunity to update the baseline profile in ComposeAdvanced at the same time.
l
What does PXX means in the output you just showed? Trying to understand how I should read it exactly. Also, which device are theses results from?
y
P50 = median. The middle time of frames. half took less, half took more.
P99 is the time that only 1% took more than.
A pixelwatch.
l
Can you get the threshold percentile that is more than 16ms to render a frame? BTW, the margin seems quite thin to me, more than 10ms to render a frame means there's only so much extra you can do before you get dropped frames blob thinking fast
b
would be interesting to know the
P
for 16ms
y
Or a feature request for a JankMetric. Feedback can be submitted here https://developer.android.com/jetpack/androidx/releases/benchmark#feedback
l
I noticed that the whole app is smoother when the watch face is not set. I guess it keeps being rendered even while in the background, or the system, or the library is doing something that eats in the UI thread or in the CPU overall blob thinking fast
y
If you can confirm that, definitely raise a bug. It shouldn't be calling you when watchface is not on screen
b
could it be that your background is not fully opaque? Not sure if that should change anything but just in case.
l
I'm not using a
Theme.Wallpaper
descendant
279 Views