Enhancing App Performance: Grab’s Journey with R8 and Profile Guided Optimization

In the fast-paced world of mobile applications, performance is key to user satisfaction. Grab, a leading app in Southeast Asia, recently embarked on a significant optimization journey to enhance its performance, focusing on reducing cold start delays and App Not Responding (ANR) spikes that were prevalent after updates.
Understanding the Challenges
Before implementing optimizations, Grab faced substantial challenges related to app initialization. The primary issue stemmed from the overhead associated with reading numerous DEX files, which delayed app launches and caused ANR spikes. While Google Play’s Cloud Profiles offered some level of optimization for standard user flows, they fell short in optimizing critical user journeys specific to Grab, such as initializing Dagger dependency graphs during the app launch.
Implementing Custom Baseline Profiles
To address these challenges, Grab adopted a custom Baseline Profile that integrated essential user journeys into Google Play’s Cloud Profiles. This strategic move ensured that key code paths were compiled into machine code right at installation, rather than relying on Just-In-Time (JIT) compilation, which can lead to performance lags in the initial days of app usage.
Achieving Significant Improvements
Through the implementation of R8 optimizations, Baseline Profiles, and Startup Profiles, Grab achieved a remarkable 27% improvement in startup time. This was composed of a 12% enhancement from R8 alone and an additional 15% from Baseline Profiles. Most importantly, these changes effectively eliminated the post-release ANR spikes that had been a consistent issue with weekly app updates.
Three Phases of Optimization
Grab’s optimization process unfolded in three strategic phases:
- Enabling R8 Optimization in Compatibility Mode: The team transitioned from the legacy Proguard file to proguard-android-optimize.txt, facilitating R8 optimizations. This was crucial given the complexity of their codebase, which has over 10 million lines of code and is over a decade old.
- Transitioning to R8 Full Mode: Launched nine months after the initial rollout, this phase allowed Grab to unlock further optimizations. The team focused on migrating specific reflection-heavy code paths to ensure compatibility with R8.
- Refining Keep Rules: The final phase involved using the R8 Configuration Analyzer to refine keep rules, ensuring that the application remained stable while maximizing optimization. This included addressing challenges with Java dynamic proxies and implementing targeted keep rules to maintain app performance.
Long-Term Performance Monitoring
Looking ahead, Grab is committed to maintaining long-term codebase health and continuous performance monitoring. The team plans to integrate automated pre-merge guardrails into their CI pipeline to prevent regressions in R8 optimization. New keep rules will require explicit justification, and ongoing evaluations will ensure that optimization gains are preserved across each release cycle.
By closely tracking R8 optimization scores through their CI dashboard, Grab is positioned to proactively address any potential performance issues before they impact users.
Conclusion
Grab’s journey through optimization showcases the importance of a structured approach to app performance enhancement. By leveraging R8 and Profile Guided Optimization, they have significantly improved startup times and reduced ANR occurrences. This not only enhances user experience but also sets a benchmark for other applications facing similar performance challenges.
Source for the original facts: Original source.




