grpc-swift
grpc-swift copied to clipboard
Reduce framework size
Hello. We are using grpc in project, which has App Clip,so that’s why we care about the size of the application (there is limit of 10 mb of uncompressed app). grpc integration (via spm) increased uncompressed app size by about 6.5 mb. Maybe there are any solutions to reduce framework size? Thanks.
Can I recommend stripping the app binary? Much of the size is likely to be symbols, and these can easily be removed by stripping them. Otherwise, you can try enabling -Osize optimizations. Beyond that, there are no ways to reduce binary size in SwiftPM.
-0size doesn't help. It reduced app clip size from 9.4 mb to 9.3 mb) Would't like to use a proxy for the grpc in App Clip, but grpc integration increases size a lot(
Tried switch from SPM to Cocoapods and AppClip uncompressed size increased from 9.4 mb to 11.5 mb 😨
If change use_frameworks! to use_modular_headers! uncompressed size will be 8.4 mb.
Have you tried stripping the binary?
Have you tried stripping the binary? I have
bitcode,Strip linked product,Dead code Strippingenabled. I've tried enableStrip debug symbols during copyfor main target and app clip target, but app size didn't change.
App clip size with bitcode, Strip linked product, Dead code Stripping enabled:
App Thinning Size Report Supported variant descriptors: Universal
-
Cocoapods with
use_modular_headers!App size: 3,9 MB compressed, 8,9 MB uncompressed -
SPM

a) [-O] App size: 4,3 MB compressed, 9,9 MB uncompressed
b) Swift compiler: [-Osize], Apple clang Optimization level: [-0s] App size: 4,3 MB compressed, 9,8 MB uncompressed
c) Swift compiler: [-Osize], Apple clang Optimization level: [-0z] App size: 4,3 MB compressed, 9,8 MB uncompressed
Don't know what can I do else to reduce grpc lib size
Thanks @Banck. Can you run the analyze_code_size.py script from Swift against your app clip and provide the output here? The invocation is probably something like: analyze_code_size.py -categorize <path/to/your/binary>.
Thanks @Banck. Can you run the
analyze_code_size.pyscript from Swift against your app clip and provide the output here? The invocation is probably something like:analyze_code_size.py -categorize <path/to/your/binary>.
- Cocoapods Cocoapods.txt
- SPM SPM.txt
Hah, sorry, can you remove the symbol stripping before you do this? That data is not all that useful without the symbols, as all we can tell is that we're using the code size mostly with code.
I also want to point out apple/swift-protobuf#1204.
Hah, sorry, can you remove the symbol stripping before you do this? That data is not all that useful without the symbols, as all we can tell is that we're using the code size mostly with code.
I also want to point out apple/swift-protobuf#1204.
Disabled Bitcode and applied these settings:

-
Cocoapods: App size: 6,4 MB compressed, 24,1 MB uncompressed Cocoapods.txt
-
SPM

App size: 7 MB compressed, 26,3 MB uncompressed SPM.txt
let me know if I did something wrong or if something needs to be done additionally. Thank you
I also want to point out apple/swift-protobuf#1204.
When I wrote the first message, I measured app size, then integrated grpc with 1 simple proto file, and measured again. The size difference was around 6.5 mb.
Is it possible for you to compare with only the impact from swift-protobuf? I'd like to isolate how much is grpc-swift. Keep your .proto files the same, but don't generate the grpc sources, only the regular protobuf ones?
Is it possible for you to compare with only the impact from swift-protobuf? I'd like to isolate how much is grpc-swift. Keep your
.protofiles the same, but don't generate the grpc sources, only the regular protobuf ones?
I measured app size with bitcode and stripping and integrated grpc via SPM: App size: 4,3 MB compressed, 9,9 MB uncompressed
Then removed all services, generated before and generated only models via comand:
protoc *.proto --swift_out=../Common/Models/Network/GRPC
-
Commented all my code related with services. Commented import GRPC in files: App size: 4,3 MB compressed, 9,8 MB uncompressed
-
removed GRPC from spm a) added NIO, NIOHTTP2, Logging and protobuf:

App size: 3,1 MB compressed, 7,1 MB uncompressed
b) added these libs:
App size: 3,3 MB compressed, 7,5 MB uncompressed
And sure, only with SwiftProtobuf: App size: 2,1 MB compressed, 4,3 MB uncompressed
Ok, so based on those numbers, the big code size contributor appears to be NIO. This is not necessarily a huge surprise to me: NIOPosix is a particularly large library. Can you clarify: is your project directly importing and depending on NIO, or on NIOCore?
For my own future reference:
- Protobuf only: 2.1 MB compressed, 4.3 MB uncompressed
- Protobuf, NIO, NIOHTTP2, Logging: 3.1 MB compressed, 7.1 MB uncompressed
- All extra libraries including grpc: 3.3 MB compressed, 7.5 MB uncompressed
This sure implies that NIO is the bulk of the weight. NIOCore should not be that heavy, but NIOPosix may well be.
Yes, I do import NIO and import NIOCore in my services, because grpc returns EventLoopFuture and I working with it, which is part of swiftNIO.
For my own future reference:
- Protobuf only: 2.1 MB compressed, 4.3 MB uncompressed
- Protobuf, NIO, NIOHTTP2, Logging: 3.1 MB compressed, 7.1 MB uncompressed
- All extra libraries including grpc: 3.3 MB compressed, 7.5 MB uncompressed
This sure implies that NIO is the bulk of the weight. NIOCore should not be that heavy, but NIOPosix may well be.
7.5 mb - it's without grpc. Grpc with all dependecies(nio, protobuf): App size: 4,3 MB compressed, 9,8 MB uncompressed
@Banck It's part of SwiftNIO, but we recently split the NIO module up into three modules: NIOCore, NIOEmbedded, and NIOPosix. This is because for iOS apps, NIOPosix is not really necessary, but it still costs code size.
Now, unfortunately grpc itself still requires NIOPosix. We don't really have great tools for making that functionality conditional at the moment, so it's extremely hard to remove.
I've noticed, that through SPM I can install grpc without swift-nio-ssl, cause Package.swift contains:
let includeNIOSSL = ProcessInfo.processInfo.environment["GRPC_NO_NIO_SSL"] == nil
.package(
url: "https://github.com/apple/swift-nio-ssl.git",
from: "2.14.0"
),
if: includeNIOSSL
And this allowed us to reduce the size of the application by 1.5 mb
from
App size: 4,8 MB compressed, 11,3 MB uncompressed
to
App size: 4 MB compressed, 9,8 MB uncompressed
If install grpc through cocoapods app size is
App size: 4,2 MB compressed, 10 MB uncompressed
I just wonder how can install grpc through cocoapods also without swift-nio-ssl ?