How to speed up android app cold start time by 50%

Many users expect your application fast to load and interact quickly. They can rate slow app poorly on the Play store, especially when they used an old and slow device. Speed up android app startup is very important for avoiding negative reviews.

Understand activity startup process

When the user opens your app, there are many launches of tasks: create process, bind application, invoke content provider, launch activity, service … For more detail, you can read here

There are 3 important phases if you want to optimize cold start time: load dex file, application onCreate, and activity onCreate

Profile app startup using Android Profiler

Android profiler is a very useful tool for detecting heavy app initialization. To using it, edit run configurations, select the profiling tab, and check start recording CPU activity on startup. Then click on the Profile button

You will see a method tracing result like this

Android Profiler

Remember while profiling app, Android Profiler makes your app laggy and slower than usual

Navigate to the application onCreate method

Be careful with any library on application onCreate. Maybe it block main thread. For example, I’m using AnalyticSdk and method readSessionConfig take 612 ms

Solutions:

  • Move library initialization to background thread
  • Lazy load library. Delay the initialization as much as possible. For example, only init AnalyticSdk when using it.

Some library read Shared Preference or do I/O operations during initialization. It’s a waste of time and maybe slow down your app

Optimize layout hierarchies

Navigate to activity onCreate method

Method setContentView take ~500ms.Because my layout hierarchies are very complex and need to be simplified. Consider using ConstraintLayout as soon as possible to optimize layout hierarchies

Be careful with ServiceLoader

ServiceLoader is good for Java, but it is really slow on Android devices because of invoking a reflective lookup. We can use R8 shrinker instead of Proguard to optimize ServiceLoader. For example, if you are using kotlin coroutines, maybe FastServiceLoader slow down your app. You can optimize it using R8

Use dagger correctly

If you have a monolithic application and using Dagger, you may face Dagger graph creation performance. For example, when a user launches the app, your app must inject AccountViewModel. AccountViewModel depends on UserManager, UserValidator, UserRepository, UserAnalytics. UserManager depends on ActionLogHelper. ActionLogHelper depends on SearchRepository, LoginRepository, FeedRepository … When AccountViewModel is created, all dependencies (UserManager, UserValidator, ActionLogHelper, SearchRepository, LoginRepository, FeedRepository …) will be created, and cause the application slow to start.

Solutions

Minimum DEX file size

The bigger and the more dex file inside APK, the longer load. If your app contains 65k+ method, multidex will be required, cause performance impact on Pre-Lollipop device. Consider using R8 shrinker or Proguard to cut off the unused method.

Using R8 shrinker instead of Proguard.

In my case, when using Proguard, there is a total 80k method but when using R8, only 60k method in APK dex file. To see how R8 work better than Proguard, please read Digging into D8 and R8

Another way to decrease DEX file size is using Dynamic Delivery. Through Dynamic Delivery, users can later download and install application components on-demand. For example, account onboarding or A/B testing feature is not a feature that every user uses. We can include onboarding, A/B testing feature as an on-demand feature, and your base APK file does not contain it, which will make your DEX file smaller. See a link bellow

Use Strict Mode for detecting heavy task

Strict Mode is a powerful tool for detecting heavy tasks on the application main thread. It not only improve your app startup but also avoid frozen frame. You can set it up like this (on debug build)

When a disk read, disk write, slow call, or network on the main thread occurred, your application will show a dialog like this

Or when activity leaked, cleartext network was detected,… your app will be crashed.

Use Android Vitals and Firebase Test Lab for monitoring app performance

Android Vitals and Firebase Test Lab are useful tools for monitoring app startup time, performance, crash, ANR … You should give attention to Android Vitals after releasing your app and use Firebase Test Lab before releasing. It may help you fix the performance issues early

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store