Understanding Important Performance Metrics in Android Development

Kayvan Kaseb
Software Development
8 min readAug 13, 2022
The picture is provided by Unsplash

Obviously, users want applications to launch quickly and render smoothly. Thus, speed is an inseparable part of app performance. To tackle performance concerns in Android apps, performance metrics could be considered as data that helps you understand how an app is performing and where you should spend time and effort to enhance it. This essay will provide you with some concepts and best-practices to understand important performance metrics in Android development.

Introduction and Overview

Obviously, users always expect Android apps to be responsive and fast to load. Speed is a vital part of app performance. How fast your Android app launches can have a prominent first impression on your users.. However, any kind of poor experience in this way can cause a user to rate your Android app poorly on the Play store, or even abandon your app.

Basically, to address performance concerns, performance metrics can be considered as data that helps you understand how an app is performing and where you should spend time and effort to enhance it. It has been shown that app startup and creating a smooth user experience have a lasting impact on user satisfaction, as well as your app’s individual business metrics. Google has offered some tools and libraries to make it easier for you to inspect, improve, and monitor performance effectively. This essay helps you to identify some key performance issues in your Android app.

Android App Startup Stages

In fact, app launch speed is a significant indicative of the overall quality of your app. This means tracking and monitoring it will help you evaluate the responsiveness of your Android app. App startup is the first point of interaction with your user. Therefore, your goal as an Android developer is to make the app startup as fast, seamless, and smooth as possible. App startup can take place in one of three stages: cold start, warm start, or hot start. The startup type is specified by the point at which your app starts.

Different Startup States, the picture is provided by Google documents

Cold start

A cold start begins when the application’s process is created. The users experience in different situations, for instance, when they install your Android app and launch it for the first time, launch the application after restarting the device, or restart the app after the system has completely stopped it for a reason. During a cold start, the Application#onCreate method is called. Everything your app needs to get started is loaded from disk. When a cold start begins, memory caches are empty. To be exact, cold starts are the slowest startup phase. You can easily experience a cold start of your app by force closing it and opening it again from the launcher as well. If a cold start takes longer than 500 milliseconds, your users can notice and might get increasingly impatient, particularly on high-end Android devices. So, maintaining cold starts as fast as possible is an extremely important issue.

Warm start

A warm start is measured from the point where Activity#onCreate is called just before your view hierarchy is inflated. At this point, some resources, such as strings and the first image resources, could already be inflated. Also, memory caches already warmed up. Warm starts typically take place when you open an app after the activity was destroyed, however, the Android application’s process is still running. This can happen if an app is running in the background for a while, but not long enough for the system to kill the entire process. In addition, whenever an orientation change forces the activity to be destroyed and recreated, warm start begins.

Hot start

Initially, a hot start of your Android application is much simpler and lower-overhead than a cold start. Hot start is the shortest app startup type. During a hot start, an application becomes visible to the user and enters the start state. at this point, the first frame is ready to be drawn, and Activity#onStart is called. A hot start happens when the app was briefly in the background and is being moved to the foreground again, for example, when you are switching back and forth between apps, you are in this phase. It is clear if all of your app’s activities are still existed in memory, then the application can avoid having to repeat object initialization, layout inflation, and rendering.

As a result, because of the nature of startup types, a cold start takes the most time. Warm start and hot start will be shorter.

Time To Initial Display (TTID)

Fundamentally, all three startup phases are measured from their corresponding start points to at least one of two end states. The default app startup end state is called Time To Initial Display (TTID). It is automatically reported when the first frame of your app is ready to be drawn. You can see TTID by opening logcat and looking at the ActivityTaskManager: Displayed tag. For example, the reported log line could be seen like the below sentence:

ActivityManager: Displayed com.android.myexample/.StartupTiming: +3s534ms

It will show you how much time it took to display a specific activity. Because this value is reported automatically, there is nothing for you to configure as a developer. Every Android app is reporting this by default.

Time To Full Display (TTFD)

As an Android developer, you are probably like APIs that enable you to customize the behavior. While TTID is reported automatically, the next state can be customized. It is called Time TO Full Display(TTFD). TTFD is an optional metric that Android can use to further optimize your app startup time. Moreover, it could be used when you are running startup benchmarks on your app. TTFD is also visible in logcat. You should report time to full display when everything is drawn on screen and the data required for the user to interact with the app is available. The API to use is Activity#reportFullyDrwan(). You can use the reportFullyDrawn() method to measure the elapsed time between app launch and complete display of all resources and view hierarchies. This can be valuable in some situations where an app performs lazy loading. In lazy loading, an application does not block the initial drawing of the window, but instead asynchronously loads resources and updates the view hierarchy. So, if we have face a lazy loading , an app’s initial display does not include all resources, you might consider the completed loading and display of all resources and views as a separate metric. In other words, To deal with this concern properly, you can manually call reportFullyDrawn() to give permission the system for knowing that your activity is finished with its lazy loading. For example, the reported log line could be seen like the below sentence:

system_process I/ActivityManager: Fully drawn {package}/.MainActivity: +1s54ms

Eventually, reportFullyDrawn() is not tied to an activity lifecycle method, and you must pick the right time to call the API.

Avoiding Jank

There are a number of problems that can create an inappropriate performance in an app. One of the most important situations to look out for in your Android application is Jank indeed. Jank happens when your app is exceedingly busy with performing some tasks on the main thread and misses the timing window to draw a frame on screen. Even though Jank can happen when scrolling, you can observe it in other cases, like when animating between scenes or transitioning from one window to another.

To avoid jank, you need to know what to look out for. The screen can be drawn many times per second. The amount of redraws per second is called frame rate. Traditional rendering rates have been 60Hz; however, many advanced devices operate in 90Hz over user interactions, like scrolling. In recent years, some devices provide even higher rates, up to 120Hz. Furthermore, devices can switch between various frame rates, depending on a user’s choice, developer’s decision, or even the device’s power or thermal state. Google has recommended Android developers to optimize for a frame rate of at least 90 frames per second. It means that all the work in between frames has to fit in a window of less than 11.1 milliseconds. The best approach to achieve this is by keeping as much work as possible off the main thread.

Important tips on measuring performance

There are some significant points in this topic that has been recommended by Google. Some has been noted here as follows:

Avoid some unnecessary initializations.

If your Application subclasses accomplish initializations that do not require to be done yet, your Android app probably waste time over startup. For instance, initializing state information for the main activity when the Android app has started up in response to an intent because the application uses just only a subset of the previously initialized state data in this special case.

Always measure release builds.

Release builds are what your users see when they start using your app. A release build can boost your app performance considerably. The resource shrinker reduces the time, which it takes to load images and other resources. With enabling this feature, the compiler makes your code more performant.

The resource Shrinker, the picture is provided by Google resources

Always measure performance on a real device.

Essentially, startup and runtime performance vary based on the device it is run on and how busy the system is at the time of measurement. Notwithstanding the fact that the Android Emulator is incredibly helpful when developing an Android app, the main system running the emulator can have different performance characteristics in comparison with the device that might run your app. As a result, you should always measure performance on a device in reality.

Measure twice or more, improve once.

You should ensure to gather metrics more than once before trying to optimize in your code. Code does not always execute at the same exact pace, even when running on the same device, depending on many factors. Hence, by performing multiple measurements, your margin for error shrinks. Also, it is more likely that optimizations have the effect that you are looking for in practice.

In conclusion

If your Android app is slow to launch, users will be frustrated before they even want to experience it. It is clear that users want apps to launch quickly and render smoothly. So, speed is a vital part of app performance. To deal with performance issues in Android applications, performance metrics could be considered as data that helps you understand how an app is performing and where you should spend time and effort to enhance it. This article discussed some concepts and best-practices to understand significant performance metrics in Android apps based on Google resources and documents.

--

--

Kayvan Kaseb
Software Development

Senior Android Developer, Technical Writer, Researcher, Artist, Founder of PURE SOFTWARE YAZILIM LİMİTED ŞİRKETİ https://www.linkedin.com/in/kayvan-kaseb