优化系列之App体积优化-Xcode编译选项优化

2,958 阅读4分钟

安装包瘦身一直是困扰我们的难题之一,好多小伙伴没有参考的方向,这篇文章就是为了那些困扰的小伙伴找到方向,也欢迎大家补充。

首先我们需要明确的概念之一就是如何体现App包被优化成功,我们参考的指标就是安装后占用的磁盘空间大小,在appstore上显示的也是这个大小。

Xcode编译选项优化方法:

1. 舍弃架构armv7:

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

2. 冗余代码剥离:

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

3.编译器优化级别:

Optimization Level 编译参数决定了程序在编译过程中的两个指标:编译速度和内存的占用,也决定了编译之后可执行结果的两个指标:速度和文件大小。

  默认情况下,Debug 设定为 None[-O0] ,Release 设定为 Fastest,Smallest[-Os]6个级别对应的含义如下:

None[-O0]。 Debug 默认级别。不进行任何优化,直接将源代码编译到执行文件中,结果不进行任何重排,编译时比较长。主要用于调试程序,可以进行设置断点、改变变量 、计算表达式等调试工作。

Fast[-O,O1]。最常用的优化级别,不考虑速度和文件大小权衡问题。与-O0级别相比,它生成的文件更小,可执行的速度更快,编译时间更少。

Faster[-O2]。在-O1级别基础上再进行优化,增加指令调度的优化。与-O1级别相,它生成的文件大小没有变大,编译时间变长了,编译期间占用的内存更多了,但程序的运行速度有所提高。

Fastest[-O3]。在-O2和-O1级别上进行优化,该级别可能会提高程序的运行速度,但是也会增加文件的大小。

Fastest Smallest[-Os]。Release 默认级别。这种级别用于在有限的内存和磁盘空间下生成尽可能小的文件。由于使用了很好的缓存技术,它在某些情况下也会有很快的运行速度。

Fastest, Aggressive Optimization[-Ofast]。 它是一种更为激进的编译参数, 它以点浮点数的精度为代价。

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

4. 配置编译选项:

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

5. 去除符号信息:

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

6. Strip Linked Product:

DEBUG下设为NO,RELEASE下设为YES,用于RELEASE模式下缩减app的大小;

7. 编译器优化,去掉异常支持:

Enable C++ Exceptions、Enable Objective-C Exceptions设置为NO,Other C Flags添加-fno-exceptions

8. Link-Time Optimization(LTO):

通过修改Build Settings中的Link-Time Optimization=Incremental

   What is Link-Time Optimization (LTO)? Maximize runtime performance by optimizing at link-time Inline functions across source files Remove dead code Enable powerful whole program optimizations
(1)将一些函数內联化
(2)去除了一些无用代码
(3)对程序有全局的优化作用

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

9. Compress PNG Files & Remove Text Metadata From PNG Fils:

为解决负优化使png格式图片增大,所以我们需要将负优化关闭,要想取消根目录下的负优化,需要将 Compress PNG Files 和 Remove Text Metadata From PNG File 都设置为 NO 才能取消。 实现代码如下:

#!/usr/bin/perl

my $PNGCRUSH = `xcrun -f pngcrush`;
chomp $PNGCRUSH;

my $compress = 0;
my $stripPNGText = 0;
my @FILES = ();

# Gather command line options.
while( @ARGV ) {
    $_ = shift @ARGV;
    next if ( $_ eq "" );
    if ( $_ =~ /-strip-PNG-text/ ) {
        $compress = 1;
        $stripPNGText = 1;
        next;
    }
    if ( $_ eq "-compress" ) {
        $compress = 1;
        next;
    }
}
my @args;
if ( $compress ) {
    @args = ( $PNGCRUSH, "-q", "-iphone", "-f", "0" );
    if ( $stripPNGText ) {
        push ( @args, "-rem", "text" );
    }
    push ( @args, $SRCFILE, $DSTFILE );
} else {
    @args = ( "cp", "$SRCFILE", "$DSTFILE" );
}

参考文档:

  1. APP的优化---IPA大小的压缩
  2. 干货|今日头条iOS端安装包大小优化—思路与实践
  3. Build settings探究之—编译优化