缩减iOS安装包大小是很多中大型APP都要做的事,一般首先会对资源文件下手,压缩图片/音频,去除不必要的资源。这些资源优化做完后,我们还可以尝试对可执行文件进行瘦身,项目越大,可执行文件占用的体积越大,又因为AppStore会对可执行文件加密,导致可执行文件的压缩率低,压缩后可执行文件占整个APP安装包的体积比例大约有80%~90%,还是挺值得优化的。

瘦身的第一步

对于app瘦身之前做过图片优化,采用脚本的方式把一些在pods中的图片迁移至imageSet下,但是这样的优化是有瓶颈的,因为它受制于图片的多少、图片在pods下的存储方式,而由于pods之间的依赖关系复杂以及有些pods中的图片为了避免全局重复问题采用resource_bundle方式来管理,这样对于图片优化极为不利,所以可以优化的空间还是有上限。这是瘦身的第一步,现在已经完成了,并且对部分采用resource_bundle方式的以的pods加以修改。这个可以参考这篇文章:点击打开链接

瘦身的第二步

考虑到整个app依赖pods多达119个,可想而之就是这些依赖是不是都全部用上了,这个是有些疑惑的,如果能够剔掉一部分无用的依赖pods,这对于瘦身也是大有益处的。但是不幸的是,在网上怎么查找也没有找到相关工具可以检测到哪些是无用的pods,这样扔下一个难题,只好采用最笨的方式去挨个手动查找了。首先去podfile里面找那些没有被依赖的pods,然后去项目中找到这些pods,然后通过找到使用这些pods的入口类,然后在在全局搜索这个类,如果有其他代码使用这个类,那么这个pod是有用的,如果找不到其他任何代码对些有引用,那可以判断这个pod是无用依赖,这样可以将此pod进行踢除。难点在于如何快速确定一个pod的入口类,这个是比较难确定。但是如果去掉的pods能通过编译并且能正常安装和运行,那说明这个pods肯定是无用的。所以根据这一操作,现在粗略去掉了六个pods以及大象相关的pods,这项工作需要比较细心,而且耗费时间,但是也是一种可行方式。现在项目所有依赖库个数减少到了97个。

瘦身的第三步

从编译选项着手,编译选项方面又可以分为下面两个方面:

1.编译器优化级别

Build Settings->Optimization Level有几个编译优化选项,release版应该选择Fastest, Smalllest,这个选项会开启那些不增加代码大小的全部优化,并让可执行文件尽可能小。

2.去除符号信息

Strip Debug Symbols During Copy 和 Symbols Hidden by Default 在release版本应该设为yes,可以去除不必要的调试符号。Symbols Hidden by Default会把所有符号都定义成”private extern”,具体意思和作用我还不清楚,有待研究,但设了后会减小体积。这些选项目前都是XCode默认选项,但旧版XCode生成的项目可能不是,可以检查一下。

其他优化还可以参考苹果的官方文档—CodeFootprint.pdf

瘦身的第四步

项目里会引入很多第三方静态库,如果能知道这些第三方库在可执行文件里占用的大小,就可以评估是否值得去找替代方案去掉这个第三方库。我们可以从linkmap中统计出这个信息,写了个node.js脚本,可以通过linkmap统计每个.o目标文件占用的体积和每个.a静态库占用的体积,并进行排序。

不过在执行这段nodejs代码时首先需要你找到编译后的可执文件信息存储文件,下面介绍如何开启并找到这个.txt文件:

1.XCode开启编译选项Write Link Map File
XCode -> Project -> Build Settings -> 搜map -> 把Write Link Map File选项设为yes,并指定好linkMap的存储位置

2.编译后,到编译目录里找到该txt文件,文件名和路径就是上述的Path to Link Map File
文件位于~/Users/yuzhuo/Library/Developer/Xcode/DerivedData/Jovi-dgmwdpjofxrufihidpjqqtomnphq/Build/Intermediates/Jovi.build/Debug-iphonesimulator/Jovi.build/Objects-normal/x86_64

这个LinkMap里展示了整个可执行文件的全貌,列出了编译后的每一个.o目标文件的信息(包括静态链接库.a里的),以及每一个目标文件的代码段,数据段存储详情。

这个文件可以让你了解整个APP编译后的情况,也许从中可以发现一些异常,还可以用这个文件计算静态链接库在项目里占的大小,有时候我们在项目里链了很多第三方库,导致APP体积变大很多,我们想确切知道每个库占用了多大空间,可以给我们优化提供方向。LinkMap里有了每个目标文件每个方法每个数据的占用大小数据,所以只要写个脚本,就可以统计出每个.o最后的大小,属于一个.a静态链接库的.o加起来,就是这个库在APP里占用的空间大小。

nodejs代码详见这里(需翻墙)。

执行脚本的命令行:node linkmap.js filepath -hl下面是我在自己上电脑执行的命令:

node linkmap.js /Users/yuzhuo/Desktop/DPMerchant-LinkMap-normal-x86_64/DPMerchant-LinkMap-normal-x86_64.txt -hl

执行脚本后的结果如下图:(太多了只给出部分的截图,全部结果放在txt文档中)

得到了这个结果可以对一些占用比较大的lib以及代码进行针对性优化了。

瘦身的第五步

删除无用代码。在项目里新建一个类,给它添加几个方法,但不要在任何地方import它,build完项目后观察linkmap,你会发现这个类还是被编译进可执行文件了。

按C++的经验,没有被使用到的类和方法编译器都会优化掉,不会编进最终的可执行文件,但object-c不一样,因为object-c的动态特性,它可以通过类和方法名反射获得这个类和方法进行调用,所以就算在代码里某个类没被使用到,编译器也没法保证这个类不会在运行时通过反射去调用,所以只要是在项目里的文件,无论是否又被使用到都会被编译进可执行文件。

对此我们可以通过脚本,遍历整个项目的文件,找出所有没有被引用的类文件和没有被调用的方法,在保证没有其他地方动态调用的情况下把它们去掉。如果整个项目历时很长,历时代码遗留较多,这个清理对可执行文件省出的空间还是挺可观的。

删除无用图片资源。在github上面发现有个开源项目Unused,通过运行这个项目可以发现无用的图片资源,并导出无用资源路径的txt文件,再通过写脚本对这些资源进行删除,下面是这个项目的运行界面。LSUnusedResources


删除无用图片资源的脚本如下图:

后续

cocoapods为每个target生成一个Pods-xxx-resources.sh的资源处理脚本,这个脚本在编译时会把项目中(Pods、Nova、Targets)所有通过xcassets管理的图片重新copy到一起导致Nova的DPScope下有一份,而DPMessage作为一个target独立存在也会存一份。(Nova下xcassets名为Images.xcassets,Pods 和其余Targets下xcassets名为Assets.xcassets)

解决方法

针对本次问题,我们在pod install跑完以后修改cocoapods的资源处理脚本,仅处理Pods和Nova中Image.xcassets管理的图片,排除掉其它Target中的图片,让各个Target独立管理。

Pods-Jovi-resources.sh脚本修改如下

这里在第4行,只需要将Jovi下名为 Images.xcassets图片管理的加入XCASSET_FILES即可,这样保证其余Targets的图片不会重复打包。

由于我们点评管家项目中只有一个target所以这种问题暂时不存在,不过这样可以避免以后出现这种问题。

修改脚本如下:


最终优化结果:

采用这么多方式去瘦身后发现效果还是喜人的,未瘦身前安装到ipone 6s上v5.1.1的大小为66.9M,减小到现在的33.4M,整体缩减33.5M,缩减率为50%,而安装包.ipa文件从开始的大小23.8M缩减到现在的14.8M,缩减率也能达到38%

iOS app瘦身优化之路相关推荐

  1. App性能优化(布局优化,线程优化,app瘦身优化,页面切换优化,App启动优化,内存优化)

    Android APP性能优化(最新总结) 在目前Android开发中,UI布局可以说是每个App使用频率很高的,随着UI越来越多,布局的重复性.复杂度也随之增长,这样使得UI布局的优化,显得至关重要 ...

  2. iOS App 瘦身实践总结

    文章最后有我的 12 条小总结. 原文始发地址:我的 GitHub 写在前面 最近公司需求不多,正好研究一下 App 瘦身的办法,写了点小总结. 如果你不知道下面几个问题,不妨可以看看文章. 使用 . ...

  3. iOS app 瘦身

    本文译自:Guides and Sample Code 的App Thinning (iOS, tvOS, watchOS) App 瘦身 App Store和操作系统通过将app定制到用户的特定设备 ...

  4. iOS APP 瘦身实战

    前言 app为什么要瘦身,无非是下面几个情况, 第一,产品或者运营觉得包体积过大了! 第二,对技术的追求,也给自己涨点绩效! 第三,面试被问到了..... 哈哈 不管哪种情况吧,要瘦身就好好玩下吧. ...

  5. iOS App瘦身---清理iOS工程里无用的图片

    LSUnusedResources 推荐一个清理图片的应用 https://github.com/tinymind/LSUnusedResources 我们的工程在经过多人后,往往会出现较多的垃圾,导 ...

  6. ios开发app瘦身

    缩减iOS安装包大小是很多中大型APP都要做的事,一般首先会对资源文件下手,压缩图片/音频,去除不必要的资源.这些资源优化做完后,我们还可以尝试对可执行文件进行瘦身,项目越大,可执行文件占用的体积越大 ...

  7. Android App 瘦身总结 第三章 代码混淆及优化

    目录 一.代码混淆proguard 二.调整第三方库 三.环境差异依赖 四.代码习惯 五.插件化 六.总结 在前两章我们分别从图片资源和jni动态库这两个方面来分析apk瘦身的优化点 Android ...

  8. Android App 瘦身总结 第一章 图片资源的优化处理

    目录 一.去除无用的资源 二.忽略占比极少的分辨率 三.优化图片 四.使用更先进的图片格式 (1)使用矢量图 (2)使用webp图片格式 五.总结 当一款App经历了大量的迭代后,apk包会越来越臃肿 ...

  9. Android App包瘦身优化

    Android App包瘦身优化 APK瘦身是对程序体验的优化,更大的APK需要占用更多的存储空间. APK的构成 APK瘦身前通过Analyze app分析出来的图片(打开方式:Android St ...

最新文章

  1. 【C++】C++11 STL算法(一):非修改序列操作(Non-modifying sequence operations)
  2. python怎么重启内核_解决jupyter运行pyqt代码内核重启的问题
  3. Error creating bean with name 'multipleEntityManagerFactory' defined in class
  4. 网站增改不要只想着收益更应该思考原有的损失
  5. 物联网设备的互操作性问题探讨
  6. bzoj1094[ZJOI2007]粒子运动 计算几何
  7. 查看scala变量数据类型_Scala文字,变量和数据类型| Scala编程教程
  8. 15-传智书城后台程序设计
  9. sql server行列转化和行列置换
  10. Smith Numbers POJ - 1142 (暴力+分治)
  11. mysql触发器新增或修改_mysql触发器实例 插入数据前更改数据值
  12. Windows文件传输小工具,网络传输文件,内网传输
  13. 九宫格游戏(java实现)
  14. 如何在Java中将Excel(XLSX)转换为Word(DOCX)
  15. oracle 新增配额,Oracle 用户配额
  16. 使用Matlab将多个图形Figure文件合并
  17. ecshop 添加会员头像功能
  18. 计算机应用技术题,计算机应用技术复习题.doc
  19. Qt 6.3.1 显示界面元素
  20. N子棋的实现方法,包括三子棋,五子棋

热门文章

  1. wwwroot中的文件删不掉
  2. 【代码审计】模板注入
  3. 【图像处理】去雾算法
  4. Linux脚本csh 遇到 Badly placed ()'s 的问题。
  5. Oracle 忘记system密码后如何找回
  6. 有吸引力的服务营销(运营营销)案例
  7. MATLAB 循环保存.mat文件
  8. 用GitChat赚钱的6种方法
  9. MBD-从一个示例看代码生成过程(rtw文件、TLC语言)
  10. python asyncio原理_Asyncio 源码分析