首先需要了解下ipa包的组成:
ipa是一个压缩包, 安装包里的主要构成是(图片+文档+二进制文件)

那么总的原则就是找到这些无效的东西清理掉。还有就是修改编译器的一些设置。

(1)项目从混编改为纯OC或者纯swift编程 (2)无用资源文件清理 (3)工具类、工具方法合并 (4)无用业务排查下线 ,无用类清理,无用第三方库清理  (4)编译选项优化(5)部分资源文件云端下载   

 

这个是头条的优化体积文章,里面提到了很多工具的使用https://www.jianshu.com/p/2c914530b54b

资源优化,清除无效图片,类,方法等

  • 资源优化
  • 删除无用图片
  • 使用 LSUnusedResources 查找无用图片。注意 [UIImage imageNamed:[NSString stringWithFormat:"icon_%d.png",index]]; 这种使用图片的方式,可能会被误删。
  • 使用Assets.xcassets来管理图片也可以减小安装包的体积
  • 删除重复资源
  • 其他技巧(选用)
  • 用 LaunchScreen.storyboard 替换启动图片。
  • 本地大图片都使用 webp。
  • 资源按需加载,非必要资源都等到使用时再从服务端拉取。
  • 可执行文件优化
  • 使用 LinkMap 分析库的使用情况
  • 三方库优化
  • 删除不使用的三方库。
  • 功能用的少但是体积大的三方库可以考虑自己重写。
  • 合并功能重复的三方库。
  • 代码分析
  • 用 AppCode 进行代码扫描。 利用AppCode 检测未使用的代码:菜单栏 ->Code->InspectCode。 最后要说:xcode BulidSetting中的设置都可以区分debug和release,如果觉得在开发的时候还想用到这些,就把debug和release分开设置就可以了
  • 去掉无用的类及文件。
  • 清理 import。
  • 去掉空方法。
  • 去掉无用的 log。
  • 去掉无用的变量。
  • 其他技巧(选用)
  • 将业务打包成动态库。如果动态库的加载时机不控制好,会影响 App 的启动速度,权衡使用。
  • 动态化。将一部分 Native 界面用 RN/Weex 重写。
  • 去除 Swift 代码,Swift 的标准库是打包在安装包里的,一般都有 10M+。然后苹果官方说等到 Swift Runtime 稳定之后会合并到 iOS 系统里,那时候使用 Swift 就不会显著增加包大小了。
  • 苹果官方的策略
  • 开启 BitCode

 

编译选项改进

1、配置编译选项 

(Levels选项内)Generate Debug Symbols  设置为NO,这个配置选项应该会让你减去小半的体积。注意这个如果设置成NO就不会在断点处停下

android包体积优化 ios 包体积优化_Time

2、舍弃架构armv7

armv7用于支持4s和4,4s是2011年11月正式上线,虽然还有小部分人在使用,但是追求包体大小的完全可以舍弃了。

android包体积优化 ios 包体积优化_Time_02

3、build setting 里 DEAD_CODE_STRIPPING = YES(好像默认就是YES)。 确定 dead code(代码被定义但从未被调用)被剥离,去掉冗余的代码,即使一点冗余代码,编译后体积也是很可观的。

android包体积优化 ios 包体积优化_android包体积优化_03

4、编译器优化级别

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

android包体积优化 ios 包体积优化_三方库_04

5、去除符号信息

Strip Debug Symbols During Copy 和 Symbols Hidden by Default 在release版本应该设为yes,可以去除不必要的调试符号。Symbols Hidden by Default会把所有符号都定义成”private extern”,设了后会减小体积。

android包体积优化 ios 包体积优化_LLVM_05

android包体积优化 ios 包体积优化_LLVM_06

6、Strip Linked Product:DEBUG下设为NO,RELEASE下设为YES,用于RELEASE模式下缩减app的大小;

android包体积优化 ios 包体积优化_LLVM_07

7、编译器优化,去掉异常支持。Enable C++ Exceptions、Enable Objective-C Exceptions设置为NO,Other C Flags添加-fno-exceptions

android包体积优化 ios 包体积优化_Time_08

Enable C++ Exceptions

android包体积优化 ios 包体积优化_LLVM_09

Enable Objective-C Exceptions

android包体积优化 ios 包体积优化_三方库_10

Other C Flags添加-fno-exceptions

8、LTO,即Link Time Optimization。

苹果在2016年的WWDC What’s new in LLVM中详细介绍了这一功能。LTO能带来的优化有: (1)将一些函数內联化 (2)去除了一些无用代码 (3)对程序有全局的优化作用

在build setting中开启Link-Time Optimization为Incremental。苹果还声称LTO对app的运行速度也有正向帮助。

android包体积优化 ios 包体积优化_三方库_11

但LTO也会带来一点副作用。LTO会降低编译链接的速度,因此只建议在打正式包时开启;开启了LTO之后,link map的可读性明显降低,多出了很多数字开头的“类”(LTO的全局优化导致的),导致我们还经常需要手动关闭LTO打包来阅读link map。

 

暂时可以看到了主流优化就是这些了,最后多说下7,8:


Enable Exceptions

Xcode中有两个关于异常捕获的选项,分别是Enable C++ Exceptions, Enable Objective-C Exceptions. 一般默认都是开启的。如果你想要在代码中使用try catch,那么一定需要开启这两个选项。

基本上Objective-C/Swift项目都使用了ARC + LLVM,在LLVM的文档中关于异常捕获是这么说的:

The standard Cocoa convention is that exceptions signal programmer error and are not intended to be recovered from. Making code exceptions-safe by default would impose severe runtime and code size penalties on code that typically does not actually care about exceptions safety. Therefore, ARC-generated code leaks by default on exceptions, which is just fine if the process is going to be immediately terminated anyway.

Google翻译:

Cocoa的习惯就是当遇到异常的时候并不打算鸟它。如果你并不关心你的破代码是不是异常安全,支持异常捕获会让你的代码运行效率降低并且增加代码体积。所以我们的处理是,当遇到异常情况时,ARC自己产生的代码就会立即崩掉,我们觉得这样挺好的。

所以如果你的项目不需要从异常中恢复,那么按照文档的说法,关掉Exception可以减少包体积并且增加运行速度。

从我们的项目来看,因为我们项目中只用了非常少量的try catch来处理一些异常,把这些代码注释掉并且关闭Enable C++ Exceptions, Enable Objective-C Exceptions这两个选项之后,项目的linkmap体积从3.7mb减少了约140kb。

Link-Time Optimization

先介绍一下什么是Link-Time Optimization (LTO) :

android包体积优化 ios 包体积优化_Time_12

Google翻译:

在链接时而非编译时的优化方式,可以增加程序运行时的速度
优化内联函数(个人认为是文件间的函数做内联优化)
移除没有被调用的方法和代码
整体优化-让你的程序变得更屌

性能:

LTO Runtime Performance
Apple uses LTO extensively internally
Typically 10% faster than executables from regular Release builds
Multiplies with Profile Guided Optimization (PGO)
Reduces code size when optimizing for size

Google翻译:

Apple已经在自己的程序里大量使用
一般来说比常规不带LTO选项要快10%
可以与按配置优化(PGO)叠加
可以用来减少代码体积

这里值得注意的是,LTO选项需要配合编译时选项来减少包体积。在Xcode的Optimization level中,如果使用-O3(让代码运行更快但是体积变大),那么配合LTO可以实现运行效率的提高,但是代码体积会变大;如果使用-Os,那么LTO才会真的的优化体积。

LTO已经做了移除无用代码的操作,即移除没有被调用的selector,这样一来我们就不用手动去搜索并移除无用的方法了,这本身就是减少包体积的方法之一(待确认)。

从实践情况来看,把开启LTO的SDK变成.ipa来看,并没有很大的体积变化,稍微减少了100k以内。聊胜于无吧。