iOS app瘦身优化之路
缩减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瘦身优化之路相关推荐
- App性能优化(布局优化,线程优化,app瘦身优化,页面切换优化,App启动优化,内存优化)
Android APP性能优化(最新总结) 在目前Android开发中,UI布局可以说是每个App使用频率很高的,随着UI越来越多,布局的重复性.复杂度也随之增长,这样使得UI布局的优化,显得至关重要 ...
- iOS App 瘦身实践总结
文章最后有我的 12 条小总结. 原文始发地址:我的 GitHub 写在前面 最近公司需求不多,正好研究一下 App 瘦身的办法,写了点小总结. 如果你不知道下面几个问题,不妨可以看看文章. 使用 . ...
- iOS app 瘦身
本文译自:Guides and Sample Code 的App Thinning (iOS, tvOS, watchOS) App 瘦身 App Store和操作系统通过将app定制到用户的特定设备 ...
- iOS APP 瘦身实战
前言 app为什么要瘦身,无非是下面几个情况, 第一,产品或者运营觉得包体积过大了! 第二,对技术的追求,也给自己涨点绩效! 第三,面试被问到了..... 哈哈 不管哪种情况吧,要瘦身就好好玩下吧. ...
- iOS App瘦身---清理iOS工程里无用的图片
LSUnusedResources 推荐一个清理图片的应用 https://github.com/tinymind/LSUnusedResources 我们的工程在经过多人后,往往会出现较多的垃圾,导 ...
- ios开发app瘦身
缩减iOS安装包大小是很多中大型APP都要做的事,一般首先会对资源文件下手,压缩图片/音频,去除不必要的资源.这些资源优化做完后,我们还可以尝试对可执行文件进行瘦身,项目越大,可执行文件占用的体积越大 ...
- Android App 瘦身总结 第三章 代码混淆及优化
目录 一.代码混淆proguard 二.调整第三方库 三.环境差异依赖 四.代码习惯 五.插件化 六.总结 在前两章我们分别从图片资源和jni动态库这两个方面来分析apk瘦身的优化点 Android ...
- Android App 瘦身总结 第一章 图片资源的优化处理
目录 一.去除无用的资源 二.忽略占比极少的分辨率 三.优化图片 四.使用更先进的图片格式 (1)使用矢量图 (2)使用webp图片格式 五.总结 当一款App经历了大量的迭代后,apk包会越来越臃肿 ...
- Android App包瘦身优化
Android App包瘦身优化 APK瘦身是对程序体验的优化,更大的APK需要占用更多的存储空间. APK的构成 APK瘦身前通过Analyze app分析出来的图片(打开方式:Android St ...
最新文章
- 【C++】C++11 STL算法(一):非修改序列操作(Non-modifying sequence operations)
- python怎么重启内核_解决jupyter运行pyqt代码内核重启的问题
- Error creating bean with name 'multipleEntityManagerFactory' defined in class
- 网站增改不要只想着收益更应该思考原有的损失
- 物联网设备的互操作性问题探讨
- bzoj1094[ZJOI2007]粒子运动 计算几何
- 查看scala变量数据类型_Scala文字,变量和数据类型| Scala编程教程
- 15-传智书城后台程序设计
- sql server行列转化和行列置换
- Smith Numbers POJ - 1142 (暴力+分治)
- mysql触发器新增或修改_mysql触发器实例 插入数据前更改数据值
- Windows文件传输小工具,网络传输文件,内网传输
- 九宫格游戏(java实现)
- 如何在Java中将Excel(XLSX)转换为Word(DOCX)
- oracle 新增配额,Oracle 用户配额
- 使用Matlab将多个图形Figure文件合并
- ecshop 添加会员头像功能
- 计算机应用技术题,计算机应用技术复习题.doc
- Qt 6.3.1 显示界面元素
- N子棋的实现方法,包括三子棋,五子棋