Keeping Up with Android App Size Growth

Keeping Up with Android App Size Growth

Tracking app size changes in CI and ensuring team accountability

At Square, we build multiple mobile apps spanning low-end to high-end Android devices as well as our own custom Square hardware. As we continue to expand our range of point-of-sale software solutions, a crucial aspect of development is reducing the size of our APKs to minimize network data usage and ensuring compliance with Google Play’s max compressed APK size of 100 MB and max Android App Bundle size of 150 MB. However, managing app size growth is a challenge with a monorepo and hundreds of mobile engineers contributing everyday. Adding large files or new libraries can unintentionally increase app sizes for different target apps and platforms.

In this post we discuss how Square tackled the issue of app size growth. We cover our strategies for reducing app size, tracking app size changes in our CI pipeline, and ensuring accountability within our teams.

Reducing App Size

Google recommends several ways to reduce app size. We already followed several of these suggestions including supporting only specific screen densities and minimizing resource use from libraries. Our CI system includes linters to guard against the inclusion of unused imported libraries and modules in commits.

To further optimize app size, we automated identifying other potential improvements using Emerge Tools. Their tools assisted us in identifying the following areas for potential savings:

  • Losslessly converting PNG to WebP
  • Detecting duplicate files and assets
  • Finding large files
  • Identifying unused native libraries

During small scale tests, we already observed the space-saving benefits of WebP conversions. However, since Emerge Tools pinpointed the exact potential savings, this catalyzed our effort to make the change across the repo.

Tracking App Changes

Initially we relied on manually tracking app download sizes using a spreadsheet. Our primary concern was the size on disk, so we examined the uncompressed size using the command:

$ zipinfo -t <your_app.apk>

This process was labor-intensive, involving downloading the relevant build, recording the size, and graphing the results. Eventually, we wrote a script to uncompress APKs and generate a report.

To dig deeper into changes between app versions, we used Android Studio’s built-in APK Analyzer as well as Jake Wharton’s Diffuse. Both tools were helpful in conducting detailed one-off comparisons, analyzing method counts, resource changes, and overall size differences.

We further automated by integrating APK size diffing into our PRs. This allowed authors and relevant teams to immediately see a message indicating the size changes on specific builds at the PR level. Given our extensive app build process, integration into our CI system was crucial. We needed to observe changes that impacted all our build variants, including developer debug versions, which tend to be larger due to the inclusion of additional instrumentation libraries for development, testing, and debugging purposes.

Although adding the APK size changes in PRs increased visibility, it seldom triggered meaningful discussions or reviews concerning app size growth. This was because messages could be easily overlooked if it did not highlight a significant size change. We needed to improve the effectiveness of the messages by emphasizing their importance. Adjusting the frequency and priority of the messages would help strike a balance between ensuring the stakeholders receive important information without overwhelming them with excessive notifications.

Our ultimate goal was to track and analyze app changes over time across all our build variants. We wanted to:

  1. Provide developers with a tool to monitor, diagnose, and improve changes in app binary sizes, rather than relying on ad hoc efforts to find and remove unused strings and resources.
  2. Comprehensively see app size changes on a graph over time.
  3. Ideally have this all completely automated.

Consequently, we began exploring the use of Emerge Tools and began automatically uploading our app builds in CI. This gave us a dashboard with an App Size Tracker graph, a build comparison tool, and an alerting mechanism.

Note: At the time of this writing, we have not yet implemented Emerge’s PR Comments feature, as support for multiple APK uploads from a monorepo has just recently been introduced.

Maintaining Accountability

After uploading APKs to Emerge Tools, we added Slack notification alerts to trigger discussions among teams. App teams would begin investigating the changes in app size, understand their root cause, and identify the responsible author and teams. Over time, we fine-tuned the notification thresholds to reduce noise and increase effectiveness.

Size Diff Threshold — To monitor changes between sequential builds, we set a Size Diff Threshold. Starting with a large threshold, we gradually tuned it lower. For instance, one team found that a 500 KB trigger on a PR was the right balance.

Absolute Size Threshold — In addition to monitoring sequential changes, we added an absolute threshold as a milestone marker. Oftentimes the Size Diff Threshold would not be hit for weeks and even months. Instead the Absolute Size Threshold would be hit, alert the team, and initiate a conversation about what changed since the previous milestone. Sometimes an investigation would identify opportunities to reduce app sizes further. Other times, there was no need to investigate further since app size growth was organic due to the expected addition of new features.

Addressing significant size increases from 3rd-party libraries — There was a significant size increase that triggered a discussion and investigation. It took some effort to identify the exact commit responsible, but the issue was successfully traced to the addition of a new native library. To mitigate the impact, we removed the x86 libraries and focused only on the ARM-based ones.

image1

X-Ray view identifying the addition of new native libraries

Cross-team boundary regressions — There was a temporary issue in device settings causing an app size increase. The owning team’s on-call engineer was alerted to the issue and coordinated a response with the team working on the fix. Traditionally, both teams would monitor the issue on a JIRA ticket and confirm it in the PR commit. With the Slack alerts and Size Tracker dashboards, both teams verified recovery from the issue immediately.

image2

While adding a new feature, some additional savings were identified to save space

Tracking impact of larger efforts — When we enabled minifying with R8, we immediately observed a significant drop in app sizes. That value was in having this automated in our CI pipeline, verifying across all our build targets, and seeing the change at the very next build.

Conclusion

With the introduction of app size tracker dashboards, our teams have gained a visual representation of app size growth over time. This allows for forecasting and predicting future trends, although app growth is not always linear due to the impact of new features. To track this growth effectively, we focused on a minimum of the past three months to capture meaningful patterns.

Reducing APK size is important. A key aspect is continuously monitoring and staying on top of changes especially as organizations grow. The implementation of new Slack alerts enabled us to quickly track the impact of major development initiatives and monitor regressions.

Table Of Contents