In a recent article, engineers from Google and Facebook provided their hints at what matters the most to reducing the time it takes for an Android app to become responsive on launch and ensuring an optimal user experience.
App startup is a key factor in keeping users engaged and for growing adoption, say Facebook engineers. The first step to improve app startup times is to measure them using Android's two standard metrics: Time-To-Full-Display (TTFD), which is the time it takes for an app to be ready for user interaction, and Time-To-Initial-Display (TTID), which measures the time for an app to become minimally functional, for example allowing the user to navigate around while still downloading some content.
Depending on the app, TTFD could be a more relevant metric than TTID, or vice-versa, but TTID is always included in TTFD, so TTID is a good starting point for optimization. Furthermore, TTID is used by Google to rank apps in Google Play listings.
Facebook’s startup metric is the percentage of app starts that they consider “bad,” which is any start that either has a TTFD longer than 2.5 seconds OR any part of startup that is unsuccessful (e.g. an image fails to load or the app crashes).
Both TTID and TTFD can be easily instrumented using Android system calls: TTID is captured by logcat's Displayed
value, while TTFD can be logged to logcat using reportFullyDrawn
.
Calling reportFullyDrawn
is an especially important practice since it provides useful information for Android to optimize resource usage to prioritize any work happening before that call, say Google engineers.
Calling this method when your app is in fully usable state will improve your app startup time. Every application should be using this API! And don’t forget to measure it.
TTID and TTFD provide solid ground to understand what can and should be optimized. To this aim, Facebook engineers enumerate a number of recommendations, such as being especially zealous about crashes at startup, parallelizing work using all available cores, and to postpone or send to the background any work that is not related to the app startup experience.
Using a cache can be a great way to speed up things and populate your app with meaningful content, but cached content should be used only when it makes sense, i.e. when it is not stale.
Evaluate whether it’s better to optimize for showing fresh content as quickly as possible with a timeout for showing stale content if the network is slow, or to just show what’s available immediately if the network is offline.
Optimizing startup times requires carefully understanding what is going on at launch, which is the critical path, and where the roadblocks are. For this, Android provides a number of tools, including trace and Jetpack Macrobenchmark: Startup. Those can also help understand if an app is trying to do too much on launch trying to initialize too many things. Another useful tool is the Jetpack App startup library, which provides a way to initialize components at application startup in a specified order.
There is much more to app startup optimization that can be summarized here, so do not miss the original article to get the full details.