TimSim
TimSim

Reputation: 4036

Slow rendering of the most basic layout

In my Android vitals 30% of my users experience slow rendering. My app has a pretty complicated UI so I made a really basic project to try to solve this problem. But it turns out it's pretty slow even with the simplest of layouts.

The layout is a centered text that Android studio offers as a template:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="slowrenderingtest.pichaipls.com.slowrenderingtest.MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/timerView"
        android:text="00:00"
        android:textSize="40dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"/>

</android.support.constraint.ConstraintLayout>

The activity that uses the layout changes the text every second (because it's a timer):

Timer updateTicks = new Timer();
updateTicks.scheduleAtFixedRate(new TimerTask() {
    @Override
    public void run() {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                Random r = new Random();
                timerView.setText(String.format("%02d", r.nextInt(60))+":"+
                                    String.format("%02d", r.nextInt(60)));
            }
        });
    }
}, 100, 1000);

When I turn on GPU profiling, this is getting pretty close to the 16ms limit for drawing each frame on some slower devices (apparently 30% of my users). Just one TextView. But here's the catch: when I first run the activity the rendering times are low but then they shoot up after a few seconds. If I keep touching the screen (there are no controls on the screen), the rendering times remain low. I'm guessing this is due to the CPU/GPU going to a low power state (so rendering takes longer).

My problem is the Android vitals. I keep seeing the warning about slow rendering times (I think anything above 5% of sessions experiencing slow rendering gets a warning) but I don't know how I can speed this up. And I'm worried it may affect my app's ranking but even with this really simple example far too many Android users have slow devices.

Can anything be done about this?

Upvotes: 5

Views: 3235

Answers (2)

Alexandru Circus
Alexandru Circus

Reputation: 5538

Try to make the textView match_parent on width...If you change the text every second, it means the TextView will need to calculate it's size each time. You will be surprised of the results...

Upvotes: 0

Ahmadul Hoq
Ahmadul Hoq

Reputation: 725

We're having the same issue is well and after some digging I suspect it's due the CPU getting idle?

Our case is similar. We have a Runnable inside which we update a TextView's text (only) every second using a Handler. The TextView resides on an item inside our RecyclerView. Interestingly, when we scroll the page, or there's some animation going on, or when interacting with the app (basically anything else other than the ticking), we get don't hit the 16ms mark. But let the device be idle and bam, each frame taking between 30-50 ms.

We tried different solutions mentioned in SO for similar situation. Like changing View's width from wrap_content to match_parent. Didn't help with the issue. We tried changing the 1000ms interval to 500, 200, 100, 50, 20, 16, 10 and only saw better results when using 16/10ms (CPU is constantly working?).

Found this article regarding CPU throttling. So probably when the CPU is idle, it's taking some more time to draw the frames?

If you look at CPU monitor in Android Studio, you'll notice CPU becomes idle as soon as nothing is happening. (Higher ones are when there's interaction, and using Nexus 5). enter image description here

But look the GPU monitor, that looks quite different from the Profile GPU Rendering bars on screen, no frames are actually crossing the 16ms mark! Not sure which GPU monitoring is the correct one. (Big yellow ones are when there's interaction). enter image description here

Upvotes: 4

Related Questions