General Motors (GM) has four unique mobile apps for their car brands with similar install sizes:
- myBuick - 449.7 MB
- myCadillac - 464.8 MB
- myChevrolet - 535.0 MB
- myGMC - 492.6 MB
Let's look under the hood to see what they share and how they can improve.
Similarities
If we look at Emerge's X-Ray for each GM iOS app, we can see they are nearly identical, with small exceptions in theming/assets. Let's take a closer look.
myCadillac X-Ray
myBuick X-Ray
myChevrolet X-Ray
myGMC X-Ray
The X-Rays show the same dynamic frameworks (heresdk.framework
, TardisHybridContainer.framework
, instabug.framework
, etc.), localized strings, Watch app, and odd.bundle
. The largest similarity is the TardisHybridContainer.framework
, a dynamically linked framework using React Native in all four apps.
While Shopify's framework doesn't appear to have significant size bloat, the TardisHybridContainer.framework is over 200 MB and can benefit from a number of low-hanging optimizations. The impact of these changes is magnified, considering it is used in all GM apps. Emerge’s insights show 170-230 MB of bloat for each app, largely from the Tardis framework.
Potential Optimizations
Scaled images outside of asset catalogs
The Tardis framework ships most of its scaled images ([email protected]
) outside of asset catalog. This means that something like illustrationdigitalkey3.png
, [email protected]
, [email protected]
are all being downloaded to a user's device, even though they'll only ever access one of those image files.
GM could shave 40+ MB from each app if it moved its scaled images into an asset catalog.
It's important to note that React Native (RN) does offer some scaled image functionality. When you use the "@2x" and "@3x" suffixes in RN, you denote specific files for specific screen densities, similar to how it works on iOS. The RN bundler will then "bundle and serve the image corresponding to a device's screen density" (docs). However, unlike native asset catalogs, the unused images will still be downloaded to a user's device, despite never being used. This is why we commonly see "scaled image" bloat in RN apps like the GM apps, Discover, or Dave.
In the case of the TardisHybridContainer, the framework is, as the name suggests, hybrid. Tardis is already using an asset catalog, so the optimal strategy is to move all scaled images to its asset catalog. For hybrid apps, RN lets you use images in a native asset catalog (docs).
To summarize, if you're building a native app, there is no reason not to use an asset catalog. If you're building a hybrid app, you can get the best of both worlds and use asset catalogs to avoid size bloat. If your app is solely RN, then the bundler will handle delivering the correct scaled image, but unused scaled images will still be included as bloat. Here's a list of notable apps with a large amount of app size from scaled images outside an asset catalog.
Duplicate and unnecessary files
The above is a 1.2 MB LaunchScreen-myBuick.png
image in the Tardis Framework's asset catalog. We found this myBuick image in the myChevrolet app. Within each app, GM is shipping assets for all four car brands, both in the Tardis Framework and in the main app asset catalog. This is happening in both the Tardis framework and the asset catalog in the main app target.
While there might be a reason to have images of the other car brands in each app, the apps have significant resource duplication in the Tardis framework. Identical directories like "energy-assistant/etc/images" | "energy-assistant-exp/etc/images" and "energy-assistant/etc/fonts" | "energy-assistant-exp/etc/fonts" are duplicated within the Tardis framework. Each app has 30+ MB of duplicate resources, much of it already in a dynamic framework.
Other optimizations
Outside of TardisHybridContainer.framework, all GM apps have significant potential for image optimization savings and minifying localized strings (stripping strings of extra comments and/or whitespace). A significant 10%-13% size decrease can be achieved in each app by a basic compression for images in odd.bundle (which seems to contain large vehicle-specific assets) and TardisHybridContainer.framework.
This is actually one of the largest instances of savings for the minification of localized strings we have seen. It's common to have comments and whitespace in localization files to be more legible for translators. While useful for translators, there's no reason comments need to be on a user's device. For myChevrolet, the bigger issue is that many of their localization files contain unicode characters.
By minifying their localization files with this one Python script, the GM apps could shave off 35+ MB (5% - 8%) of install size 🤯
Here are other apps that have high possible minification savings (+ a thread diving into FedEx):
TL;DR
The GM apps have many opportunities to reduce their mobile app size. By minifying localized strings, using asset catalogs, removing duplicate files, optimizing images, and removing app-specific images, GM can reduce the size of each app by ~35% (773+ MB total across all their apps). According to Spotify, this reduction in app size translates directly into lower data transfer volumes during app downloads and updates, resulting in measurable reductions in carbon emissions associated with digital data transmission. Because their apps share a lot of code, these low-hanging fruit fixes can help make a big impact.
Analysis Links
Here are the links to all build analysis pages referenced:
- myCadillac v6.22.0 build analysis (December '23)
- myBuick v6.22.2 build analysis (January '24)
- myChevrolet v6.22.2 build analysis (February '24)
- myGMC v6.23.0 build analysis (February '23)
- Shopify v9.144 build analysis (February '24)