At Zomato, we serve millions of active customers in more than 700 cities in India. Such a diverse spread means that our customers use a variety of devices to enjoy our services. 

To cater to this huge demand, we need to ensure speedy deliveries with a seamless app experience, across devices. And to achieve this, we look at two critical metrics: app open times and responsiveness. 

‘App Open Time’ refers to the time taken from tapping the app icon till the time the app is ready for customer interaction. When hungry customers have to wait for the app to load (even if it is a few microseconds), it can cause a lot of them to drop off, leading to an adverse effect on business.

The initial results of our optimisation efforts were not only promising but astounding. Further, with our expansion into tier-2 and tier-3 cities, we realised the need to deploy universally applicable solutions, which could be handled by devices with relatively limited processing capacity. 

So, what did we do?

We used a simple rule to analyse our overheads. We evaluated solutions based on their return on investment and the effort required to be put in by our engineering team. Based on this, we commenced a four-month-long optimisation and improvement journey.

Step 1 – Aim for perfection with Perfetto

Perfetto is a system profiling and app tracing tool by Google. It helps analyse the app by collecting system and app-level performance traces. After examining the traces, we noticed issues such as high inflation time and significant libraries load time in our app’s performance and prioritised these issues through the low-effort-high-gain approach.
Legacy SDKs and libraries took a significant amount of time in the app startup, so removing them was our priority. This exercise helped us improve the app startup time by ~20%.

Step 2 – Laziness helps (sometimes)

Content providers are initialised after the Application class but before Application’s onCreate(). Many third-party (3P) libraries such as Facebook and Firebase use content providers’ property to initialise themselves during the startup. This can cost the performance of any app unless these libraries are required on the app launch.

App startup library helps resolve this issue by providing an interface to order the libraries’ initialisations, saving precious time. We mainly use Facebook SDK during the login process, so we removed its auto initialisation, and only initialised the SDK if the consumer selects the Facebook login method. This quick yet significant fix helped us reduce the startup time by ~6%.

Step 3 – Stub them out

We focus on a custom startup time to analyse the app’s performance. It’s not just the Android’s startup time but also extends to the point where customers can start interacting with the app. So, the next step was to improve the inflation time of the views. This was critical as the rendering and inflation of the view itself can take a significant amount of time in a complex UI structure like ours.

For this, we turned to ViewStub, which increased efficiency by creating views but only adding them to the view hierarchy if required. The optimal strategy here was to flatten the view hierarchy and merge layouts along with ViewStubs in the login activity. These changes significantly improved the inflation time by 7%.

Step 4 – Cache me if you can

Android Studio provides Profiler, a powerful tool to track CPU activity, memory usage, and trace analysis like Perfetto. In Profiler, we can take a deep look at the app’s functioning unlike Perfetto, which mainly focuses on the broader view. We found some inefficiencies in our views and memory usage, so we tried to improve the caching mechanism and reuse the views as much as possible. Thanks to this, we achieved a massive drop of 60% in out of memory issues. 

Quick tips 

  1. Try not to use coroutines during the app startup phase as they take a significant amount of time to initialise. Instead, one can use ExecutorService to handle background tasks, as the Zygote process already initialises it, hence no overhead.
  2. Always check the merged manifest file and find out those content providers that are not required at the startup phase.

These steps led to:

  1. Performance gains, which helped us create a smoother customer experience. 
  2. UI improvements and reduced jank.
  3. A 20% uptick in customers landing on a fully-loaded and usable homepage. This flow is a key business metric at Zomato.

According to Firebase Performance’s cold startup metric, our app startup time improved by 25% on average, and for low-mid-range devices, by over 30%. 

“Working on such a large scale app comes with its challenges, but we are always ready to explore new ways to improve the experience for our customers. This project helped us understand the performance metrics in a deeper manner. Tools like Profiler and Systrace can be overwhelming, but if one is aiming for a blazing-fast app, it’s definitely worth the effort.”

Shubham Pathak – Engineering Team

At Zomato, we are always 1% done. So, we continue to build an increasingly faster and smoother app experience for you and strive to be the most preferred and loved food delivery company. If what we do at Zomato excites you, reach out to me on LinkedIn.


Please enter your comment!
Please enter your name here