How to Shrink iOS App Size: Proven Strategies and ROI from Alibaba.com
This article explains why app package size matters for download conversion and uninstall rates, presents business value data, and details a comprehensive set of iOS app slimming techniques—including component, resource, and compilation optimizations, code removal, and anti‑regression mechanisms—along with practical ROI analysis and implementation steps.
Preface
Package size is a key performance metric for apps, directly affecting download click‑through rates, installation success, and uninstall rates. The size is simply the sum of all file sizes, but slimming techniques are complex, involving Xcode build settings, LLVM compiler options, CocoaPods, image compression, and CI.
This article summarizes Alibaba.com app slimming techniques and strategies, outlining business value, analysis methods, slimming technologies, and anti‑degradation mechanisms, with ROI guidance to avoid wasted effort.
Business Value
Each 6 MB increase reduces download conversion by 1 %
Google’s 2019 data shows a 6 MB increase leads to a 1 % drop in conversion; a 10 MB reduction can raise global conversion by 1.75 % (higher in emerging markets). Larger packages also cause users to avoid cellular downloads, cancel slow installs, or encounter network issues.
20 % of users uninstall due to limited storage
A 2021 Clevertap survey of 2,000+ users found storage constraints as a top uninstall reason.
App Store size limits
iOS apps compatible with iOS 8 must keep the Text segment under 60 MB; packages over 200 MB cannot be downloaded over cellular.
Analysis Techniques
Result Metrics: App Store install size and download size
View in App Store Connect → TestFlight → Build Metadata → App Store File Size.
Process Metric: Xcode build size
The IPA built by Xcode differs from the App Store size because Apple trims architectures and assets. Use lipo to split architectures and assetutil to split asset catalogs.
lipo "originalExecutable" -thin arm64 -output "arm64Executable" xcrun --sdk iphoneos assetutil --scale 3 --output "${targetFolder}/Assets3.car" "${sourceFolder}/Assets.car"Build Package Composition
Understand iOS project structure (shell project, Pods, static/dynamic libraries, resources) and IPA contents (Mach‑O binaries, frameworks, Assets.car, bundles, etc.) to identify optimization opportunities.
Pod Module Size
Analyze each Pod’s code and resource size by parsing link‑map data for static libraries and using lipo for dynamic libraries, then aggregating resource copy scripts.
Runtime ObjC Class Coverage
Determine which classes are loaded at runtime; classes with 0 % load rate can be removed. Detection uses the +initialize method and the isInitialized flag in the meta‑class.
// objc-class.mm
Class class_initialize(Class cls, id inst) {
if (!cls->isInitialized()) {
initializeNonMetaClass(_class_getNonMetaClass(cls, inst));
}
return cls;
}
// objc-runtime.h
#define RW_INITIALIZED (1<<29)
bool isInitialized() {
return getMeta()->data()->flags & RW_INITIALIZED;
}Unused Image Resources
Parse the resource copy script to list all copied assets, then compare with strings extracted from the binary to find unused images.
// Pods-targetName-resource.sh
install_resource "${PODS_ROOT}/APodName/APodName.framework/APodName.bundle"
install_resource "${PODS_ROOT}/BPodName/BPodName.framework/BPodName.xcassets"
install_resource "${PODS_ROOT}/BPodName/BPodName.framework/xxx.png" strings executable | grep 'xxx' > cstrings.txtUnused Classes in Binary
Use otool to read __objc_classrefs and __objc_classlist sections, then diff to locate unreferenced classes.
otool -v -s __DATA __objc_classrefs xxxMainClient
otool -v -s __DATA __objc_classlist xxxMainClient
nm -nm xxxMainClientSlimming Techniques
Two perspectives: pure technical (compile‑time optimizations) and logical (module‑level removal). Technical optimizations have low risk but modest gains; logical removal can yield higher ROI by disabling or deleting whole modules.
Component Slimming
Prioritize components with 0 % class load rate, then unused functional components, then duplicate components.
0 % Load Rate Components
Entire Pods whose classes never load can be safely removed after business confirmation.
Unused Functional Components
Modules that are no longer used (e.g., expired A/B tests, old promotion code) can be refactored out.
Duplicate Functional Components
Identify and consolidate duplicated libraries across teams.
Resource Slimming
Focus on large resources, lossy compression, duplicate removal, icon fonts, and multilingual string reduction.
Large Resources
Prioritize assets >100 KB; e.g., a 900 KB audio file reduced by 700 KB.
Lossy Compression
Compress PNG/JPG with tools like TinyPNG, pngquant, pngcrush, optipng, advpng; choose the best result per image.
# Determine APNG format, skip compression
function isApng() {
ret=`grep "acTL" "$1"`
lastWord="${ret##* }"
if [[ $lastWord == "matches" ]]; then
echo "YES"
else
echo "NO"
fi
}
# Example compression commands
pngquant 256 -s5 --quality 70 --output "$tmpFileName" -- "$tmpOrigName"
pngcrush -brute -rem alla -nofilecheck -bail -blacken -reduce -cc -- "$tmpOrigName" "$tmpFileName"
optipng -o6 -i0 -out "$tmpFileName" -- "$tmpOrigName"
advpn -4 -z -- "$tmpFileName"Unused Resources
Static analysis found 12 MB of unused resources across 20 modules.
Duplicate Icons
Hash resources at build time, deduplicate, and replace lookups via a mapping table.
On‑Demand Resources (ODR)
Use iOS ODR to download rarely used assets at runtime.
Iconfont
Replace raster icons with scalable iconfont to reduce size and improve visual consistency.
Multilingual Strings
Reduce 6 MB of string tables (20 languages, ~4000 entries each) to 4 MB.
Compilation Optimizations
Key ROI steps: set Optimization Level to -Oz, enable LTO, share static libraries between dynamic libs and the main binary, compress linker output, hide symbols, strip dead code, and configure Asset Catalog Compiler for space.
-Oz Optimization Level
主工程Release
Optimization Level :-Oz
Framework工程
Optimization Level :-OzLTO (Link‑Time Optimization)
Enable incremental LTO for cross‑module inlining and dead code removal.
主工程Release
Link-Time Optimization 设置为 Incremental
framework工程Release
Link-Time Optimization 设置为 IncrementalDynamic Library Reuse
Configure dynamic libs to lookup symbols in the main binary, disable bitcode, and export only needed symbols.
Other Linker Flags -> -undefined dynamic_lookup
Enable Bitcode -> NoStrip Linked Product
主工程Release
Deployment Postprocessing :YES
Strip Linked Product :YES
Strip Style :All Symbols
Framework工程
Deployment Postprocessing :YES
Strip Linked Product :YES
Strip Style :Non-Global SymbolsSymbols Hidden by Default
主工程Release
Symbols Hidden by Default : Yes
Framework工程 静态库/动态库
Symbols Hidden by Default : NODead Code Stripping
主工程
Dead Code Stripping : YesAsset Catalog Compiler
主工程
Asset Catalog Compiler->Optimization 设置为 spaceC++ Symbol Visibility
Other C++ Flags->添加 -fvisibility=hidden
__attribute__((visibility("default"))) void MyFunction1() {}
__attribute__((visibility("default"))) void MyFunction2() {}Code Decommissioning
Based on ObjC class coverage, gradually remove unused classes; ROI is low but safe when verified.
Flutter Specific
Apply Oz, Dart symbol stripping, tree‑shake icons, and remove NOTICES to reduce size.
Anti‑Degradation Mechanisms
Incremental Standards and Integration Gates
Define package size baselines and reject builds that exceed a 100 KB increase per module unless compensated by other slimming.
Business Health Ratio
Calculate Business PV / Business size to identify low‑value large modules for further slimming.
Conclusion
Implementation steps: 1) Set goals and track download conversion, install size, and Xcode build size. 2) Build analysis pipelines (Pod size, ObjC coverage, unused resources). 3) Apply ROI‑driven slimming: component > resource > compilation > code removal. 4) Enforce anti‑degradation via incremental standards, CI gates, and health‑ratio analysis.
References
[1] 白鲸出海:2019谷歌开发者大会首日看点:Google Play的新变化
[2] googleplaydev:Shrinking APKs, growing installs
[3] clevertap:Why Users Uninstall Apps
[4] Scanning unused classes tool: https://github.com/xuezhulian/classunref
[5] TinyPNG API
[6] pngquant
[7] pngcrush
[8] optipng (lossless)
[9] advpng
[10] LTO introduction
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
