同事在群里发 说 TestFlight 里我们那个 App 显示"大小 280MB",后面跟一句"这个正常吗"。功能做得不算多,体积怎么就上去了?花半天看,大头不在业务代码——是几处从立项起就没人动过的构建配置,加上两个功能重叠的第三方库。这类问题问的人多,真去拆开看过体积构成的人少——好在包体积属于少数能"拆开数"的东西,量出来再动手,比拍脑袋稳。
这篇按"体积从哪来"分四类排查,每一类给出确认方法和瘦身手段。 思路都是先测、再改、改完重新出包对比。
IPA 解压之后,里面有个和 App 同名的可执行文件(Mach-O 格式),它经常是体积的大头。在 macOS 上两条命令能先看个大概:
1size -m MyApp.app/MyApp # 看各段大小:__TEXT 是代码,__DATA 是数据2lipo -info MyApp.app/MyApp # 看包里有哪些 CPU 架构
__TEXT 段明显偏大的话,逐个查这几处:
-Os(按体积优化);用
-O(按速度优化)会大一圈,这俩换来换去就差在这里。Strip Linked Product 和
Deployment Postprocessing 在 Release 下都设成 YES,调试符号不进包。Dead Code Stripping 在 Release 下默认开着,没人调用的函数链接时被丢掉——工程配置要是被人动过,翻出来确认它还在。lipo -info 如果列出了 x86_64,说明模拟器版本混进上架包里了——正常的上架包只含 arm64。还有一条 Swift 项目的额外账:泛型用得多,编译器会为不同具体类型生成多份特化代码,
__TEXT 会比同功能的 Objective-C 项目大一些。这是语言特性带来的,先把上面几条配置层的收益吃干净,再考虑代码层怎么收拾。
资源的问题在于"隐形":图片、音视频、字体摊在包里,没谁逐个统计过。
按名字动态加载的资源不能乱删:
UIImage(named:)、按路径从 Bundle 读的音视频、storyboard/xib 里引用的文件,编译器看不到这类"按字符串找文件"的引用。删掉不会报错,运行时才崩。
otool -L 或者
dyld_info -dependents 拉:对主可执行文件和几个大框架各跑一遍,链接和加载了哪些库一目了然,功能重叠的合并掉。改配置、换资源、合依赖之后,判断标准就一个:重新出一版包,跟旧的比。走 Xcode 的话看 Archive 导出的体积报告;用命令行发布的话,Fastlane 的 gym 出包后直接对比 IPA 大小。
不挂在 Xcode 工具链上的环境也是同一条路。 KXApp 这类一键构建出包的工作流里,配置改完重新构建一版,出包结果摆在面前——效果不看配置文件,看包。
对比时留意口径:IPA 文件大小、商店里显示的下载大小、装机后的实际占用,这三个数不相等,前后用同一个口径量,不然容易自己吓自己。
有 CI 的话,把体积对比固化进流水线更省心:每次构建把 IPA 大小和体积报告归档下来,涨了自动提示,比发版前临时抱佛脚主动得多。
体积优化不是一次性的压缩动作,是构建配置一项项安排的过程——看出哪一类占了大头,挑对应手段,改完重新出包验证。
排查顺序也有个省事的走法:如果体积是某次发版突然涨上去的,先对比相邻两个版本的体积报告,改动集中在哪一块一望便知;如果是慢慢涨上来的,再按上面四类从头过。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70051050/viewspace-3182418/ ,如需转载,请注明出处,否则将追究法律责任。