App startup time

App launch can take place in one of three states, each affecting how long it takes for your app to become visible to the user: cold start, warm start, or hot start. In a cold start, your app starts from scratch. In the other states, the system needs to bring the running app from the background to the foreground. We recommend that you always optimize based on an assumption of a cold start. Doing so can improve the performance of warm and hot starts, as well.

To optimize your app for fast startup, it’s useful to understand what’s happening at the system and app levels, and how they interact, in each of these states.


Cold start

A cold start refers to an app’s starting from scratch: the system’s process has not created the app’s process. Cold starts happen in cases such as your app’s being launched for the first time since the device booted, or since the system killed the app. 

At the beginning of a cold start, the system has three tasks. These tasks are:

  1. Loading and launching the app.
  2. Displaying a blank starting window for the app immediately after launch.
  3. Creating the app process.

As soon as the system creates the app process, the app process is responsible for the next stages:

  1. Creating the app object.
  2. Launching the main thread.
  3. Creating the main activity.
  4. Inflating views.
  5. Laying out the screen.
  6. Performing the initial draw.

Application / App creation

When your application launches, the blank starting window remains on the screen until the system finishes drawing the app for the first time. At that point, the system process swaps out the starting window for your app, allowing the user to start interacting with the app.

If you’ve overridden Application.onCreate() in your own app, the system invokes the onCreate() method on your app object. Afterwards, the app launch the main thread, also known as the UI thread, and tasks it with creating your main activity.

Activity creation

After the app process creates your activity, the activity performs the following operations:

  1. Initializes values.
  2. Calls constructors.
  3. Calls the callback method, such as Activity.onCreate()

Typically, the onCreate() method has the greatest impact on load time, because it performs the work with the highest overhead: loading and inflating views, and initializing the objects needed for the activity to run.


Hot start

A hot start of your application is much simpler and lower-overhead than a cold start. In a hot start, all the system does is bring your activity to the foreground. If all of your application’s activities are still resident in memory, then the app can avoid having to repeat object initialization, layout inflation, and rendering.

However, if some memory has been purged in response to memory trimming events, such as onTrimMemory(), then those objects will need to be recreated in response to the hot start event.

A hot start displays the same on-screen behavior as a cold start scenario: The system process displays a blank screen until the app has finished rendering the activity.


Warm start

A warm start encompasses some subset of the operations that take place during a cold start; at the same time, it represents more overhead than a hot start. There are many potential states that could be considered warm starts. For instance:

  • The user backs out of your app, but then re-launches it. The process may have continued to run, but the app must recreate the activity from scratch via a call to onCreate().
  • The system evicts your app from memory, and then the user re-launches it. The process and the activity need to be restarted, but the task can benefit somewhat from the saved instance state bundle passed into onCreate().

Detect and diagnose problems

Android vitals in Play Console

Android vitals can help improve your app’s performance by alerting you, via the Play Console, when your app’s startup times are excessive. Android vitals considers your app’s startup times excessive when the app’s:

  • Cold startup takes 5 seconds or longer.
  • Warm startup takes 2 seconds or longer.
  • Hot startup takes 1.5 seconds or longer.

Time to initial display

In Android 4.4 (API level 19) and higher, logcat includes an output line containing a value called Displayed. This value represents the amount of time elapsed between launching the process and finishing drawing the corresponding activity on the screen. The elapsed time encompasses the following sequence of events:

  1. Launch the process.
  2. Initialize the objects.
  3. Create and initialize the activity.
  4. Inflate the layout.
  5. Draw your application for the first time.

Example logcat:

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

To find elapsed time in Android Studio, you must disable filters in your logcat view. Disabling the filters is necessary because the system server, not the app itself, serves this log.

ActivityManager: Displayed com.android.myexample/.StartupTiming: +3s534ms (total +1m22s643ms)

In this case, the first time measurement is only for the activity that was first drawn. The total time measurement begins at the app process start, and could include another activity that was started first but did not display anything to the screen. The total time measurement is only shown when there is a difference between the single activity and total startup times.

Time to full display

You can use the reportFullyDrawn() method to measure the elapsed time between application launch and complete display of all resources and view hierarchies. This can be valuable in cases where an app performs lazy loading. In lazy loading, an app does not block the initial drawing of the window, but instead asynchronously loads resources and updates the view hierarchy.
For example, your UI might be fully loaded, with some text drawn, but not yet display images that the app must fetch from the network.

To address this concern, you can manually call reportFullyDrawn() to let the system know that your activity is finished with its lazy loading. When you use this method, the value that logcat displays is the time elapsed from the creation of the application object to the moment reportFullyDrawn() is called. Here’s an example of the logcat output:

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


References:
https://developer.android.com/topic/performance/vitals/launch-time#cold

Leave a comment