App Modularization and Module Lazy Loading at Instagram and Beyond
Article Summary
Instagram's app was getting bloated. More engineers, more features, slower cold starts, and ballooning app size threatened the lean experience users loved.
The Instagram engineering team tackled this by modularizing their codebase and implementing lazy loading for feature modules. This 2017 article breaks down their approach to keeping the app fast as it scales, focusing primarily on Android implementation.
Key Takeaways
- Modularization creates strict boundaries between features to prevent unnecessary code loading at startup
- Lazy loaded modules compile to separate dex files, loaded only when needed
- On Dalvik, this approach reduces multidex performance penalties significantly
- Instagram open sourced their framework: ig-lazy-module-loader on GitHub
- Modules load with under 50ms latency at p99, enabling seamless user experience
By separating features into lazily loaded modules, Instagram improved cold start times, reduced disk footprint, and maintained developer velocity as the codebase grew.
About This Article
Instagram was dealing with four scaling issues. The app was getting bigger to download from the store, it took longer to start up and become interactive, it used more disk space, and the growing codebase made it harder for developers to work quickly.
Instagram engineers broke the app into isolated modules, then compiled each module into separate dex files. They used lazy loading so features only loaded when users got close to or opened them. Developers could also swap modules during iteration without rebuilding everything.
Lazy loading moved methods out of the main dex file, which reduced the overhead from Dalvik multidex. Feature code ended up clustered together in memory for better performance. The team could also ship different feature sets to different users, which made the initial app smaller.