Android Performance Checking and Solving(1): Frozen Frames
Why you have to be frozen… when you can dance like crazy
One day i move to a new team when i was working on Messenger App. This new team called “Android App Performance Team”. As a part of the team we should fixed performance issued. But a lot of issues regarding performance i heard from user even from managements.
What should we do? What our first step?
The answer is :
Collect the problems data:
First stem is collect Data about what is our issues, what is the biggest issue and what is the most important issue to fix.
1. User Feedback
At that time Google Play Console still shown (ANR and Frozen Frame) report at Vital section, but now only ANR rate still shown.
Okay i think those data is enough for us to know what is the biggest and the most important issue.
This what we got : Lagging issue / UI rendering issue.
Learning UI Rendering Issue, Frozen Frames and Friends
There are 3 kinds/levels of UI rendering issues :
UI Rendering is the act of generating a frame from your app and displaying it on the screen. To ensure that a user’s interaction with your app is smooth, your app should render frames in under 16ms to achieve 60 frames per second (why 60fps?). If your app suffers from slow UI rendering, then the system is forced to skip frames and the user will perceive stuttering in your app. We call this jank.
Frozen frames are UI frames that take longer than 700ms to render. This is a problem because your app appears to be stuck and is unresponsive to user input for almost a full second while the frame is rendering. We typically recommend apps to render a frame within 16ms to ensure smooth UI. However, when your app is starting up or transitioning to a different screen, it’s normal for the initial frame to take longer than 16ms to draw because your app must inflate views, lay out the screen, and perform the initial draw all from scratch. That’s why Android tracks frozen frames separately from slow rendering. No frames in your app should ever take longer than 700ms to render.
The worst thing that can happen to your app’s responsiveness is an “Application Not Responding” (ANR) dialog.
In Android, application responsiveness is monitored by the Activity Manager and Window Manager system services. Android will display the ANR dialog for a particular application when it detects one of the following conditions:
- No response to an input event (such as key press or screen touch events) within 5 seconds.
BroadcastReceiverhasn't finished executing within 10 seconds.
Too long to read those explanation? i make it simple:
- Slow rendering : UI rendering with ( 50% of all frames, >16ms<=700ms)
- Frozen frames : UI rendering with (>700ms<=5s)
- ANR : UI rendering with (>5s)
What we got from those Explanation Above?
- UI take a long time to render.
- If we kill the slow rendering then we kill the Frozen Frames and ANR.
- Slow Rendering is hard to kill, but we can start with kill Frozen Frames.
Find Frozen Frames
Before we kill Frozen Frames we have to know where is the Frozen Frames happened.
Find Frozen Frames is very tricky at that time, because google play console didn’t show the location of Frozen Frames, even now Frozen Frames its self has removed from warning report Google Play Console Vital.
And we realized that It will be good if there are some analytics data regarding performance issues.
And. We found Firebase Performance Monitoring
Firebase Performance Monitoring is a service that helps you to gain insight into the performance characteristics of your iOS, Android, and web apps.
Two years ago, First time we use Firebase Performance Monitoring, when the version is still beta. Even still Beta, this service is very use full. And one and half year ago Firebase Performance Monitoring has a stable version.
And we found the screen. Now we need to know the specific method call or root cause.
Find The Root Cause
Before we search for the root cause, we need to know one thing :
Android System use UI Thread to rendering the UI. So make sure UI Thread only for rendering UI, not other process (IO Process or complex computation process).
Try to Find Out Some Long UI Thread Process
Instead of we searching on code manually, or using timer manually. we can use some tools to help us find out some Long UI Thread Process.
Android Studio (Cpu Profiler ->Method call execution)
This Profiler is very helpful for us, you can trace and analyse the method call execution including time, name of function, and thread that use for process.
Finally we can kill Frozen Frames
We found the screen also the method call or root cause. Now we need to fix this.
Because the problem is there are some process that aren’t UI rendering running on UI Thread. So the fix is move that process to other thread. e.g: IO process run on IO thread.
How to move?
Using Runnable is the simplest way, and this execution is very fast. But to make sure its run on specific type of thread for example IO thread, the extra code is a bit complex. And if you want to run UI thread inside runnable you need Handler class.
AsyncTask is like a Runnable, but this class include Handler inside. So calling UI Thread from AsyncTask is super easy.
ReactiveX is a combination of the best ideas from
the Observer pattern, the Iterator pattern, and functional programming.
You need to learn the syntax and behaviour of this. And if you can use this your life is easier. Move thread with RX Java very simple, as simple as snap the you finger.
We Learn UI Rendering Issue, We Learn that don’t do computation or IO Process on UI Thread. We find the right tools using Android Studio Profiler and Firebase Performance Monitoring, We found the issues and we solve this by moving the process to other Thread.