Dilip Sharma | October 13, 2023 | 4 min read
How we improved our Android app startup time by over 20% with Baseline Profile

A seamless and speedy user experience can determine an app’s success by improving retention rates and thereby making a big difference for a business. In our commitment to providing an exceptional user experience, we utilize a wide range of optimization methods and techniques, and in this blog, we shine light on one such technique: Baseline Profiles. This game-changing approach has significantly enhanced our app’s startup, demonstrating its power in the realm of Android app optimization.

Baseline Profiles help apps to start and run faster by optimizing critical code paths ahead of time, resulting in a smoother and seamless user experience. When we include a Baseline Profile in an app or software, Android Runtime (ART) can make the important parts of the code run faster before we even use them. This helps the app work better for everyone who uses it, whether they just downloaded it or updated it. This special way of making things faster is called Profile Guided Optimization (PGO) which means that the app can start faster, work smoother, and be better overall right from the very first time you open it.

How does it work?

To understand its working, let’s see how an app compilation works. The source code is first compiled into bytecode and then converted into Dalvik Executable (DEX) bytecode for Android’s runtime. Resources like images and layouts are compiled too. Then, these components are packaged into an APK, signed with a digital certificate, and then installed on an Android device.

Upon the initial execution following an installation or an update, the app’s code functions in an interpreted state until it undergoes “Just-in-time” compilation (read more). While Java and Kotlin code within the APK is converted into dex bytecode, full translation into machine code is avoided (as of Android 6) due to storage and loading expenses. Both app classes and methods that observe regular usage, including those pivotal for app initiation, are logged in a profile document. As the device enters an idle mode, ART compiles the applications using these profiles, resulting in an accelerated launch for subsequent app instances.

Cloud Profiles

Starting with Android 9 (API level 28), Google Play also provides Cloud Profiles. As an app operates on a device, the profiles generated by ART are transmitted via the Play Store app and aggregated within the cloud. Once a sufficient number of profiles have been uploaded for a specific application, the Play app uses the aggregated profile for subsequent installs.

Problem With Cloud Profiles

While Cloud Profiles are great when they are available, they aren’t always ready to be used when an app is installed. Collecting and aggregating the profiles usually takes several days, which is a problem in the context of frequent weekly app updates. This often results in users updating their apps prior to the Cloud Profile being ready. The Google Android team has been looking for other ways to improve the latency of profiles.

Baseline Profiles are a new mechanism to provide profiles which can be used on Android 7 (API level 24) and higher. A baseline profile is an ART profile generated by the Android Gradle plugin using a human readable profile format, which can be supplied by apps and libraries. An example might look like this:

HSPLandroidx/compose/runtime/ComposerImpl;->updateValue(Ljava/lang/Object;)V
HSPLandroidx/compose/runtime/ComposerImpl;->updatedNodeCount(I)I
HLandroidx/compose/runtime/ComposerImpl;->validateNodeExpected()V
PLandroidx/compose/runtime/CompositionImpl;->applyChanges()V
HLandroidx/compose/runtime/ComposerKt;->findLocation(Ljava/util/List;I)I

Baseline Profiles are created during build time, becoming a component of the APK shipped to the Play Store, and subsequently distributed to users upon app downloads.They fill the gap in the ART Cloud Profile pipeline, when Cloud Profiles are not yet available, and automatically merge with Cloud Profiles once they are.

Getting Started with Baseline Profiles

Generating Baseline Profiles is straightforward. One can use the Jetpack Macrobenchmark library to create a simple instrumentation test. This test should cover critical user journeys within the app, guaranteeing the optimization of the most important parts.

While creating a test for a user journey within our app, we encountered significant challenges concerning the configuration of our Zomato application. These challenges encompassed tasks such as permission management and the establishment of mock locations. When we ran our app in Firebase Test Lab or Emulator, it was not able to run the user journeys test because of the different environment. We needed to replicate the similar configuration of the app, mimicking how a typical user interacts with it. Given the limited availability of resources on writing tests with UiAutomator, we navigated these hurdles through a process of trial and error, drawing insights from various sources to successfully integrate these functionalities into our testing framework.

We’ve implemented a GitHub Action that automates the execution of these tests, ensuring the generation of a baseline profile on Firebase Test Lab just before each app release.

gcloud firebase test android run \
--type instrumentation \
--app ${{ env.APK_PATH }} \
--test ${{ env.TEST_PATH }} \
--device model=oriole,version=33,locale=en,orientation=portrait \
--directories-to-pull /sdcard/Android/media/com.zomato.benchmark \
--test-targets "class com.zomato.benchmark.BaselineProfileGenerator" \
--timeout 1200s \
--num-flaky-test-attempts 1

Once generated, the profile file is placed in your app’s source folder. It gets merged with profiles from other dependencies and is included in your app bundle, ready to be distributed via Google Play.

Verifying the Benefits
You can verify the performance benefits of Baseline Profiles through field metrics, such as Google Play Vitals, or by running benchmarks locally on a device. The results are typically faster app startups and smoother experiences. It reduced our app cold startup by ~20% from 3.47% to 2.81%.

A Better User Experience

In conclusion, Baseline Profiles are a game-changer for Android app developers. They offer a straightforward way to enhance your app’s performance without major code overhauls. New users get faster initial experiences, and existing users enjoy more consistent performance. So, why not make a Baseline Profile and give your users the snappiest app experience possible?

References

facebooklinkedintwitter

More for you to read

Technology

apache-flink-journey-zomato-from-inception-to-innovation
Data Platform Team | November 18, 2024 | 10 min read
Apache Flink Journey @Zomato: From Inception to Innovation

How we built a self-serve stream processing platform to empower real-time analytics

Technology

introducing-pos-developer-platform-simplifying-integration-with-easy-to-use-tools
Sumit Taneja | September 10, 2024 | 2 min read
Introducing POS Developer Platform: Simplifying integration with easy-to-use tools

Read more about how Zomato is enabling restaurants to deliver best-in-class customer experience by working with POS partners

Technology

migrating-to-victoriametrics-a-complete-overhaul-for-enhanced-observability
SRE Team | August 12, 2024 | 11 min read
Migrating to VictoriaMetrics: A Complete Overhaul for Enhanced Observability

Discover how we migrated our observability metrics platform from Thanos and Prometheus to VictoriaMetrics for cost reduction, enhanced reliability and scalability.

Technology

go-beyond-building-performant-and-reliable-golang-applications
Sakib Malik | July 25, 2024 | 6 min read
Go Beyond: Building Performant and Reliable Golang Applications

Read more about how we used GOMEMLIMIT in 250+ microservices to tackle OOM issues and high CPU usage in Go applications, significantly enhancing performance and reliability.