Sitemap
Dipien

Productivity tools & ideas for Android, Kotlin & Gradle developers.

30 ideas to reduce your Android App Startup times

The Ultimate Guide to Accelerating Your Android App: tips for Reducing Startup Times and Boosting User Satisfaction

15 min readMar 28, 2023

--

Press enter or click to view image in full size

With an ever-growing number of Android apps available in the Google Play Store, developers must work diligently to ensure their app stands out among the competition. One of the most crucial factors in an app’s success is its startup time — the time it takes for the app to load and become responsive after a user launches it. In today’s fast-paced digital world, users expect apps to load almost instantaneously, and any delays can result in user dissatisfaction and potential abandonment.

User Retention and Engagement

Slow startup times can lead to users abandoning an app in favor of competitors or simply losing interest. A recent study shows that 40% of users will abandon an app if it takes more than three seconds to load. This number increases exponentially as the load time increases, indicating that users have little patience for slow-performing apps. Consequently, it is crucial for developers to optimize their apps to minimize startup times and keep users engaged.

User Frustration and Brand Perception

A slow startup time can also lead to user frustration and a negative perception of the brand behind the app. Users often associate slow-loading apps with poor quality, unprofessionalism, and a lack of attention to detail. This negative perception can dissuade users from using the app, sharing it with others, or engaging with other products from the same brand. In contrast, a fast-loading app can help create a positive image, encouraging users to continue using the app and promote it among their peers.

In this article, we’ll dive into 30 ideas to help reduce your Android app startup times and keep users engaged.

1. Fix startup crashes first

Crashes during startup are the most frustrating and quickest way to get users to abandon your app, so this should be your first priority before starting to reduce startup times.

2. Minimize app size

A smaller app size means faster installation, updates, and quicker load times. Consider the following strategies to reduce your app size:

3. Use code shrinkers

Code shrinkers like ProGuard and R8 can help reduce app size by removing unused code and resources. This can result in faster startup times and improved performance.

To activate shrinking, obfuscation, and optimization, you should include the relevant code in your project-level build.gradle.kts file.

android {
buildTypes {
getByName("release") {
// Enables code shrinking, obfuscation, and optimization
isMinifyEnabled = true
// Enables resource shrinking
isShrinkResources = true
// Includes the default ProGuard rules files that are
// packaged with the Android Gradle plugin.
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}
}

4. Skip debug code on production

You should organize your code, so you avoid having debug code on production. Some examples of code that shouldn’t be present in production are:

If you have non-production code (for example, debug code) under src/main, your release APK will have it. Organizing your code under the correct source set will help you to reduce your app startup times. You can read more about this topic in the following article:

5. Keep your libraries up to date

Using the latest library versions can be a great way to reduce the startup times of your app. The latest versions often have better performance optimizations, bug fixes, and feature improvements that can make your app run more efficiently and smoothly.

6. Minimize usage of third-party libraries

When creating an Android application, it is common to utilize external libraries in order to enhance the app’s functionality and flexibility.

It’s important to try to reduce to the minimum the usage of third-party libraries. The more libraries you integrate into your app, the longest your startup times will be. Most of the third-party libraries for analytics or tracking include content providers for initialization, causing an increase in your app startup times. Some examples are Firebase Analytics, Firebase Performance Monitoring, Firebase Crashlytics, Sentry, Instabug, Adjust, New Relic, etc.

Try to reduce these libraries to the minimum and avoid integrating multiple libraries that do the same measurements. Consider the sampling as a possibility, so only a fraction of your users are affected by the startup times penalties caused by these libraries.

7. Use Jetpack WorkManager for Background work

Don’t block the main thread unless you have to. Move I/O and non-critical paths work off the main thread. Remove, delay, or move to the background any work that’s not directly related to a startup experience until after the app has started. The Jetpack WorkManager library can help you to move work to the background. WorkManager is a library that provides a simplified way to schedule background tasks. It takes care of compatibility issues, ensuring that your app runs efficiently on different devices and versions of Android.

8. Avoid using the runBlocking builder on the main thread

Try to avoid using the runBlocking builder on the main thread, because it runs a new Kotlin coroutine and blocks the current thread until its completion.

9. Use Shared Preferences apply()

Use Shared Preferences apply() instead of commit() on the main thread. The commit() method is synchronous and could pause your UI rendering.

10. Implement Jetpack App Startup Library

The App Startup Library simplifies the startup process by providing a single point of initialization for all components. This can lead to improved startup times and more manageable code.

If you use Content Providers to initialize parts of your app, then you should migrate them to the Jetpack App Startup library. It provides a performant way to initialize components at application startup. Both library developers and app developers can use this library to streamline startup sequences and explicitly set the order of initialization.

Some useful links about the library:

11. Disable not needed content providers

Turning off unneeded content providers can be beneficial for decreasing app launch duration on Android, as it optimizes the app’s initialization process and enhances performance. Content providers serve as components within Android applications that handle access to organized data sets, facilitating data exchange between various apps. Although content providers can be advantageous, they might also cause slower startup times if not properly managed.

By deactivating content providers that are not crucial for the app’s launch, you minimize the overhead associated with initialization during app startup. Each content provider listed in the app’s manifest file is activated at the time of application startup, even if it is not needed right away. Disabling non-essential content providers conserves time and system resources, leading to a faster launch.

If your app uses the Firebase SDK, the FirebaseInitProvider is normally automatically merged into your app build by the Android build tools when doing a build with Gradle. Each content provider adds a penalization to your startup times. So, removing this provider can help to your startup performance.

In your manifest, add an entry for FirebaseInitProvider, and make sure to use a node marker to set its tools:node attribute to the value "remove". This tells the Android build tools not to include this component in your app:

<provider
android:name=”com.google.firebase.provider.FirebaseInitProvider”
android:authorities=”${applicationId}.firebaseinitprovider”
tools:node=”remove” />

Because you removed FirebaseInitProvider, you’ll need to perform the same init somewhere in your app (in your own Jetpack App Startup Initializer, to ensure Analytics can measure your app correctly):

if (FirebaseApp.initializeApp(context!!) == null) {
Log.w(TAG, "FirebaseApp initialization unsuccessful")
} else {
Log.i(TAG, "FirebaseApp initialization successful")
}

More info here.

12. Optimize startup code in ContentProviders and Initializers

Startup performance can suffer when your ContentProviders and Jetpack App Startup Initializers are not optimized. Optimizing them allows for faster initialization during app launch.

13. Optimize startup code in Application class

Launch performance can suffer when your code overrides the Application object, and executes heavy work or complex logic when initializing that object. Your app may waste time during startup if your Application subclasses perform initializations that don’t need to be done yet.

Other challenges during app initialization include garbage-collection events that are impactful or numerous, or disk I/O happening concurrently with initialization, further blocking the initialization process. Garbage collection is especially a consideration with the Dalvik runtime; the Art runtime performs garbage collection concurrently, minimizing that operation’s impact.

Optimize the code in your Application class to reduce startup times. To avoid time-consuming operations, consider using Jetpack App Startup to remove logic from the Application onCreate, or Jetpack WorkManager to load data asynchronously.

Lazy initialization defers the initialization of objects or resources until they’re needed. This approach can reduce initial load times by spreading out the initialization process. Try to do lazy initialization as much as possible in order to execute initializations or configuration as later as possible, on the first usage, inside of Activity#onCreate.

14. Don’t Prewarm App Features

Devices have limited resources, and starting up each feature in an app takes time. The more features an app starts, the longer it will take to begin.

Some apps start features or libraries early to make them faster when needed. However, this “warming up” uses shared resources and can slow down the app’s startup, which may affect how much users like the app.

A well-made and optimized app can start quickly on a top-of-the-line device, and users might not notice any slowness.

But many users, especially in developing countries, have devices with lower performance. These devices have less power, slower disk speeds, and limited network and CPU time. The same well-made app can take much longer to start on a low-performance device, making users unhappy and possibly hurting the app’s success.

You can read more about this topic on this article from Google:

15. Use a custom Splash Screen

A splash screen can provide users with immediate visual feedback, giving the illusion of a faster startup time. Ensure your splash screen is lightweight and transitions smoothly to the app’s main content.

Starting with Android 12, migrating to the SplashScreen API is required. This API enables a faster startup time. The compat library backports the SplashScreen API to enable backward compatibility and to create a consistent look and feel for splash screen display across all Android versions.

See the Splash screen migration guide for details.

16. Avoid loading multiple activities on app startup

Avoiding loading multiple activities during app startup can help reduce app startup times on an Android app by minimizing the overhead associated with activity initialization and ensuring a more efficient user experience. Each activity in an Android app has its own lifecycle and requires its own initialization process. By avoiding loading multiple activities during app startup, you can minimize the time spent on initializing and setting up various UI components and resources, leading to faster startup times.

By only loading a single activity during startup, developers can create a faster and more responsive app for their users.

17. Minimize main activity creation time

Activity creation often entails a lot of high-overhead work. Often, there are opportunities to optimize this work to achieve performance improvements. Such common issues include:

  • Inflating large or complex layouts.
  • Blocking screen drawing on disk, or network I/O.
  • Loading and decoding bitmaps.
  • Rasterizing VectorDrawable objects.
  • Initialization of other subsystems of the activity.

The onCreate(), onStart() and onResume() methods runs during the app’s startup process. Minimize the work done in them to reduce startup times.

18. Optimize layouts & custom views

Optimizing layouts & custom views is important to make Android apps start faster. When an app starts, the Android system sets up the layout files and creates View objects in memory. Complex or inefficient layouts or views can slow down the startup. Here’s why optimizing them can help make app startup times faster:

  1. Faster layout setup: An optimized layout has fewer nested ViewGroups and a simpler view hierarchy. This means the system needs to set up fewer XML elements, saving time and speeding up the startup.
  2. Quicker screen display: Android needs to process the view hierarchy when showing the UI. Simple layouts and views need less processing, so the UI is shown faster.
  3. Less memory used: An optimized layout with fewer views uses less memory. This leaves more resources for other tasks and makes the app start faster and run smoother.
  4. Reduced overdraw: Overdraw happens when the system redraws the same pixel multiple times due to overlapping views. By optimizing the layout and removing extra views or backgrounds, you can reduce overdraw and improve performance.

19. Caching main screen content

In some cases, caching the content required to render the first screen can help you to save startup time. You will need to evaluate whether it’s better to optimize for showing fresh content as quickly as possible or to just show what’s available immediately if the network is offline.

20. Call reportFullyDrawn()

The following article explains a new feature called IORap, introduced in Android 11 to improve application startup times.

You can help IORap out by invoking the reportFullyDrawn() callback when your app completes its startup.

21. Optimize network requests

Optimizing network requests can help reduce app startup times by minimizing latency and payload size. Use caching, compress data, and prioritize network requests to improve performance. Try to reduce the number of network calls needed to render the first screen or even unify multiple calls, in order to save time.

22. Optimize database access

Optimizing database access is essential for speeding up app startup times in Android applications. Databases are crucial for storing and retrieving data, and efficient access ensures a smooth user experience. Use Room, which is part of Android Jetpack, to make SQLite access more manageable and improve performance.

Optimizing database access can make Android apps start faster by reducing the number and complexity of queries during app startup, which improves performance. With fewer queries, there’s less time spent on data retrieval and processing, resulting in quicker app startups.

Using lazy loading or on-demand data fetching only retrieves data when it’s needed, saving time and resources during app startup. Using suitable and efficient data structures for storing and getting data speeds up database tasks, cutting down the time spent on searching, sorting, and processing data, and making the app start faster.

Caching and indexing can greatly speed up database access. Caching stores frequently accessed data in memory, reducing database queries, while indexing organizes data for faster searching, leading to quicker data retrieval.

Running database tasks asynchronously on a background thread prevents the UI from freezing during startup. Offloading time-consuming tasks to another thread keeps the app responsive while database tasks are running. Grouping database tasks into one batch improves performance by reducing the overhead of executing each task individually, saving time on database access during app startup.

23. Use ViewModel and LiveData

ViewModel and LiveData are components of Android Jetpack that help you manage UI-related data in a lifecycle-conscious way. This can lead to more efficient code and improved app startup times by promoting efficient data management, reducing redundant operations, and ensuring a more responsive user interface.

24. Implement Android’s Paging Library if needed

The Paging Library is a part of Android Jetpack that helps you load and display data more efficiently, reducing the impact on app startup times.

Here’s a brief explanation of how it contributes to faster startup times:

  1. Loading data in chunks: The Paging Library allows you to load data in smaller chunks or pages, rather than loading the entire dataset at once. This reduces the time and resources required to fetch, process, and display the data, leading to faster app startup times.
  2. On-demand data loading: The Paging Library fetches data only when it’s needed, such as when a user scrolls through a list. This on-demand data loading approach minimizes the initial load time and ensures that the app starts up quickly.
  3. Reduced memory usage: By loading only a subset of data at any given time, the Paging Library helps reduce the memory footprint of your app. This leads to better performance and faster startup times, as the app doesn’t need to allocate memory for the entire dataset.
  4. Smooth scrolling experience: The Paging Library ensures a smooth scrolling experience by efficiently handling data loading and display. This prevents UI stuttering and lag, ensuring a responsive app startup experience for users.

25. Use Instant Apps when possible

Instant Apps, introduced by Google in 2016, are designed to streamline the user experience by providing access to specific parts of an Android app without the need for a full installation. By using Instant Apps, developers can significantly reduce app startup times and provide a more efficient experience to users. Here’s how Instant Apps contribute to faster app startup times:

  1. No installation required: Instant Apps do not require a complete app installation, so users can access the app’s content and features quickly. This eliminates the time spent downloading and installing the app, resulting in faster startup times.
  2. Smaller app size: Instant Apps are designed to be lightweight and focus on specific functionalities. This means they generally have smaller APK (Android Package) sizes, which can be loaded and executed more quickly than a full app.
  3. On-demand feature modules: Instant Apps use Android App Bundles and Dynamic Delivery to deliver only the required feature modules for a particular user interaction. By loading only the necessary components, Instant Apps can start up faster than a full app that needs to load all its resources.
  4. Optimized resources: Developers need to optimize their Instant Apps to ensure that they load quickly and efficiently. This includes minimizing the number of resources, compressing images, and using efficient coding practices. These optimizations contribute to a faster startup time.
  5. Efficient network requests: Instant Apps are designed to minimize network requests and use caching strategies to reduce the need for data retrieval. By minimizing network latency, Instant Apps can start up more quickly than their traditional counterparts.
  6. Reduced dependency initialization: Instant Apps are meant to be lean and focused, which means that they typically have fewer third-party libraries and dependencies to initialize during startup. This leads to a faster app startup time, as there is less overhead during the initialization process.

26. Use Baseline Profiles

Baseline Profiles are a list of classes and methods included in an APK used by Android Runtime (ART) during installation to pre-compile critical paths to machine code. This is a form of profile guided optimization (PGO) that lets apps optimize startup, reduce jank, and improve performance for end users. Using baseline profiles in Android apps can help reduce app startup times by optimizing the app’s performance based on real-world usage data.

See the Baseline Profiles docs for details.

You can also see these official articles and videos about using Baseline Profiles to improve startup times:

In this Android Developers Backstage podcast episode, they chat about Baseline Profiles:

27. Roll out your app to Google Play incrementally

Android improves an app’s performance by building a profile of the app’s most important hot code and focusing its optimization effort on it. It relies on the device to optimize apps based on these code profiles, which means it could be a few days before a user sees the benefits.

Android uses the initial rollout of an app to bootstrap the performance for the rest of the users. ART analyzes what part of the application code is worth optimizing on the initial devices, and then uploads the data to Play Cloud. Once there is enough information, the code profile gets published and installed alongside the app’s APKs.

These optimizations help improve cold startup time without an app developer needing to write a single line of code. You just need to roll out your app using alpha, beta, or incremental rollout channels to get this benefit.

You can read more about this in the following article:

28. Use Hilt for Dependency Injection

Hilt is a dependency injection (DI) library for Android, built on top of the popular Dagger library. While Hilt itself might not directly reduce app startup times, it simplifies and streamlines the dependency injection process, making it easier to optimize your app’s performance and startup times.

Consider using a dependency injection framework like Hilt that creates objects and dependencies when they are injected for the first time.

29. Understand performance locally

  • The Macrobenchmark library helps you measure larger end-user interactions, such as startup, interacting with the UI, and animations.
  • The Microbenchmark library helps analyze performance of more granular, application-specific situations.
  • Use Android Studio to record and view system traces or stack sampling traces.
  • To begin recording traces using Android Studio, see Record traces. For additional information, check out this video series.
  • Simpleperf is a native stack sampling tool for Android. It can be used to profile both Android applications and native processes running on Android. It can profile both Java and C++ code on Android.
  • Perfetto is a platform-wide tracing tool available on Android 10 (API level 29) and higher. For more information, see Overview of Perfetto traces.

30. Understand performance in production

  • Android vitals is a feature in Google Play Console that provides insights into your app’s performance. Use this information to optimize your app and improve startup times.
  • The Firebase performance SDK is a tool that helps you gain insights into your app’s performance, allowing you to identify and resolve issues that may be affecting startup times.

Support Us

There are different ways to support our work:

  • With Bitcoin Lightning using Alby:
  • With PayPal or a credit card using Ko-fi.

--

--

Dipien
Dipien

Published in Dipien

Productivity tools & ideas for Android, Kotlin & Gradle developers.

Maxi Rosson
Maxi Rosson

Written by Maxi Rosson

I write about Productivity tools & ideas for Android, Kotlin & Gradle developers. Founder of smarthomecompared.com where I compare the best Smart Home device.

Responses (1)