Profiling app size on iOS
Intro
Today I’d like to show you how to do a proper size analysis of an App or an SDK on iOS.
I’ll try to be as short as possible, so fasten the seat belts 🤠
Building the app
Let’s create a new empty app and integrate some third-party SDK via SPM. For example StreamChatSwiftUI.
1. Open Xcode
2. Create New Project... -> iOS App -> Product name: `Size`; Interface: `SwiftUI` -> Next -> Create
3. File -> Add Package Dependencies -> `stream-chat-swiftui` -> Add Package -> Add to Target: `Size` -> Add Package
5. Make sure the `DEBUG_INFORMATION_FORMAT` build setting is set to `DWARF with dSYM File` for more detailed analysis
4. Select a development team in the Signing & Capabilities editor
5. Product -> Archive -> `Size.xcarchive`
Profiling the size
This is where we get to a crossroads, because there are a bunch of ways to get the size of a binary.
We will look at some of them, from the simplest to those that offer the most comprehensive analysis.
Disk Usage CLI
-
Measure your app
app_path="Size.xcarchive/Products/Applications/Size.app" size_in_mb=$(echo "scale=2; $(du -sk "${app_path}" | cut -f1) / 1024" | bc) echo "$size_in_mb MB"
- Where:
* `du` is an abbreviation for "Disk Usage" * `bc` is an abbreviation for "Basic Calculator" or "Bash Calculator" * `1024` is the number of KB in MB * `scale=2` is an argument to round the result to required number of decimal places * `-sk` is an argument to get the size of a file/folder in KB * `cut -f1` is an argument to get rid of the file path in the output
- Result:
13.23 MB
-
Measure your binary
app_binary_path="Size.xcarchive/Products/Applications/Size.app/Size" size_in_mb=$(echo "scale=2; $(du -sk "${app_binary_path}" | cut -f1) / 1024" | bc) echo "$size_in_mb MB"
- Result:
12.08 MB
Bloaty
-
Install bloaty, a size profiler for binaries, crafted by Google
brew install bloaty
-
Profile you binary
app_binary_path="Size.xcarchive/Products/Applications/Size.app/Size" dsym_binary_path="Size.xcarchive/dSYMs/Size.app.dSYM/Contents/Resources/DWARF/Size" bloaty ${app_binary_path} --debug-file=${dsym_binary_path} -d compileunits -n 0
-
Where:
* `-d compileunits` is an argument to get app size split per file * `-n 0` is an argument to specify the maximum fetch depth
-
Result:
FILE SIZE VM SIZE -------------- -------------- 8.1% 1004Ki 7.9% 1004Ki [__TEXT,__text] 6.8% 837Ki 6.7% 848Ki [__LINKEDIT] 2.4% 293Ki 2.3% 293Ki /Library/Developer/Xcode/DerivedData/Size-chfnnfxxtxfvxabrjimspcolpjyk/SourcePackages/checkouts/stream-chat-swift/Sources/StreamChat/WebSocketClient/Events/MessageEvents.swift 2.4% 292Ki 2.3% 292Ki [__DATA_CONST,__const] 2.4% 291Ki 2.3% 291Ki /Library/Developer/Xcode/DerivedData/Size-chfnnfxxtxfvxabrjimspcolpjyk/SourcePackages/checkouts/stream-chat-swiftui/Sources/StreamChatSwiftUI/ChatChannelList/SearchResultsView.swift 0.0% 0 2.1% 261Ki [__DATA,__bss] 1.9% 234Ki 1.9% 234Ki [__TEXT,__const] 1.9% 231Ki 1.8% 231Ki [__DATA,__data] 1.6% 198Ki 1.6% 198Ki [__TEXT,__swift5_typeref] 1.5% 184Ki 1.5% 184Ki /Library/Developer/Xcode/DerivedData/Size-chfnnfxxtxfvxabrjimspcolpjyk/SourcePackages/checkouts/stream-chat-swiftui/Sources/StreamChatSwiftUI/ChatChannelList/ChatChannelNavigatableListItem.swift 1.4% 170Ki 1.4% 170Ki /Library/Developer/Xcode/DerivedData/Size-chfnnfxxtxfvxabrjimspcolpjyk/SourcePackages/checkouts/stream-chat-swift/Sources/StreamChat/ChatClient.swift ... ... ... 100.0% 12.1Mi 100.0% 12.3Mi TOTAL
Emerge Tools
And finally, let’s see the magic Emerge Tools is capable of 🪄
1. Zip your app's xcarchive: `zip -r Size.zip Size.xcarchive`
2. Sign up for a free account at emergetools.com
3. Verify your email
4. Open emergetools.com/dashboard
5. Uploads -> Upload a local build -> Drag your `Size.zip`
6. Click on the `View build analysis` link
7. Point to any module to find out its size or search for any filename, class name, etc...
Postscript
If you want to get an idea of how a third-party SDK affects the size of your app, just do the same without importing an SDK and compare the results.