zoukankan      html  css  js  c++  java
  • 【iOS】APP的优化---IPA大小的压缩

    众所周知,在App Store中超过一定大小的文件只能使用WiFi下载(近期提升到了150M,之前是100M)。虽然提升了一点,但是我们仍需要注意安装包的大小。毕竟除了游戏很少有人喜欢下很大的应用。

    那么如何知道是哪些文件占得空间比较大呢?有一个比较简单的方法就是找到IPA包,解压得到.app文件,显示包内容,就可以查看到里面的东西了。

    *注意:.app bundle是经过压缩的,并且有些文件的压缩效果要比别的文件好,所以压缩后的效果才是才是最重要的。不过一般情况下在压缩前最大的文件,在压缩后依旧是最大的文件。我们可以将某个文件删除,然后在Finder中右键单击,选择压缩,这样可以更加精确的测量文件压缩效果。

    bundle如果你不懂的话可以查看这篇文章。参考

    看到这里我们就知道一个ipa里面大文件都有哪些了,然后就可以针对性的修改。

    说了上面一些,下面开始说一些干货吧。

    首先是Xcode编译选项优化。经过下面这些设置,你的APP就会小很多。

     Xcode编译选项优化方法:

    1.舍弃架构armv7

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

     

    2.冗余代码剥离

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

     3.编译器优化级别

    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

    接下来就是资源文件了,这些都是占大头的。

    在开发中我们会使用一些本地图片,本地资源,三方SDK之类的。这些东西会占用很大的内存。下面我会一一解决。

    1.本地资源文件

    一些大图片或者音视频我们不会设置成网络,而是存储在本地,这就导致的IPA包的加大。

    精简本地资源文件方法:
    (1)压缩资源文件,如使用 ImageOptim 或者 TinyPng 来压缩图片,还可以在调整一下音视频的码率,减小体积;
    (2)把一些资源放在网络上,如一些非第一时间加载需要的资源文件(需要根据不同业务逻辑进行判断)放置在网络上,在加载完成后静默下载存储在本地。留存之后使用。
    (3)简单的图片可以使用代码自动生成。很类似的图片,仅仅只有颜色不同,可以通过代码处理图片的颜色。
    (4)Xcode 中也会有一些图片相关设置,Compress PNG Files 和 Remove Text Medadata From PNG Files。前者打包的时候自动对图片进行无损压缩,后者会移除 PNG 图像名称、作者、版权、创作时间、注释等信息。

     1 -(UIImage*)imageChangeColor:(UIColor*)color{
     2   UIGraphicsBeginImageContextWithOptions(self.size, NO, 0.0f);//获取画布
     3   [color setFill];//画笔沾取颜色
     4   CGRect bounds = CGRectMake(0, 0, self.size.width, self.size.height);
     5   UIRectFill(bounds);
     6   [self drawInRect:bounds blendMode:kCGBlendModeOverlay alpha:1.0f];//绘制一次
     7   [self drawInRect:bounds blendMode:kCGBlendModeDestinationIn alpha:1.0f];//再绘制一次
     8   UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
     9   UIGraphicsEndImageContext();//获取图片
    10   return img;
    11 }
    12 
    13 + (UIImage *)getLaunchImage{
    14   CGSize viewSize = [UIScreen mainScreen].bounds.size;
    15   NSString *viewOr = @"Portrait";//垂直
    16   NSString *launchImage = nil;
    17   NSArray *launchImages = [[[NSBundle mainBundle] infoDictionary] valueForKey:@"UILaunchImages"];
    18   for (NSDictionary *dict in launchImages) {
    19     CGSize imageSize = CGSizeFromString(dict[@"UILaunchImageSize"]);
    20     if (CGSizeEqualToSize(viewSize, imageSize) && [viewOr isEqualToString:dict[@"UILaunchImageOrientation"]]) {
    21       launchImage = dict[@"UILaunchImageName"];
    22     }
    23   }
    24   return [UIImage imageNamed:launchImage];
    25  }

    补充:
    音频的压缩参考WWDC中的Audio Development for Games,里面介绍了如何有效的处理音频。常规来说,我们要使用AAC或MP3来压缩音频,并且可以尝试降低一下音频的比特率。有时候44.1khz的采样是没有必要的,稍微低一点的比特率也不会降低音频的质量。
    图片方面尽量使用8-bit图片(使用8-bit的PNG图片会比32-bit的图片能减少4倍的压缩率。但是8-bit的图片支持最多256种不同的颜色,所以8-bit的图片一般只应该用于一小部分的颜色图片。例如灰度图片最好使用8-bit。)针对32-bitt的图片尽量使用高压缩的比率:利用Adobe Photoshop的Save For Web可以减小JPEG和PNG的图片大小。在Xcode中,默认情况下,会自动的使用pngcrush来压缩.png图片。

    2.Assets.xcassets里的图片

    在版本迭代中我们也会遇到一下界面调整,图片更换的情况,尤其是在一些活动或者主题色变化时,经常会往里面添加新图片,一些老图片可能就不会删除,久而久之,图片大小就越来越大。

    精简图片的方法:
    (1)使用在线压缩png图片网站来压缩图片:compresspngtinypng
    (2)一些比较大体积的背景图片压缩成.jpg格式的。
    (3)删除无用图片
    用LSUnusedResource这个软件查找项目中没有用到的图片,然后删除,当然不一定特别准确,有一些[UIImage imageNamed:[NSString stringWithFormat:@"icon_%d",index]]这样使用的图片也会被列在未使用图片中。
    也可以使用这个脚本工具可以大范围检测程序中没有用到的图片http://blog.csdn.net/songhongri/article/details/21833069
    使用方法:1.将.sh文件放到所检测工程的目录下,
         2.cd到该目录下,
         3.执行脚本:sh unusedImage.sh
    注意:这里在删除未应用的图片时注意第三方库里的不能删除,保险起见相同文件夹下的最好在工程里手动再搜索一次,确定没有使用到,就可以删除了。

    3.SDK

    我之前开发中遇到的一个APP,内容较多功能比较复杂,SDK就有将近200m,虽然知道App Store会有压缩,可是还是很大,这是我们就需要精简SDK了。

    精简SDK方法:
    (1)最基本的就是去除无用的SDK
    (2)尽量使用同一个公司下的SDK,我之前就见过一个开发分享用shareSDK,统计用的友盟,bug分析用的buggly。还有其他的SDK,基本就是一个功能用一套,这不就是很大的问题吗?在国内公司基本上都是往全的方向做,一个完整的SDK基本上就能包含大部分功能了,所以使用同一个公司的内容,缺失再补充SDK就是一个很好的方法
    (3)在使用SDK的时候,我们不需要下载全部的功能,我们可以选择性下载功能,用不到的功能我们不需要下载。

     4.代码

    代码方面也有很多需要注意的地方,如一些readme文件和一些迭代中产生的无效代码等。

    精简代码的方法: 

    (1)将数据从代码中剥离出来
    将所有的资源(例如很长的字符串)从代码中剥离出来,并存入外部文件,这样会减小最终文件下载的大小,因为这些文件的压缩效果更好。(参考iOS App Store Specific Considerations中的完整介绍。)
    (2)无用代码的删除
    通过 AppCode 打开对应的工程文件 选择 Code -> inspect Code 分析代码,去掉无用的引用及代码。查找内部使用到的第三方库,一方面可以进行删减代码,用不到的类,可以直接删除,还有把第三方库中的图片资源删除掉。
    (3)一些文档的替换
    在开发中我们可能会有一些文档之类的在代码中,但是在迭代后可能会没有用,我们可以删除这些东西来减小体积。 

  • 相关阅读:
    利用DTrace实时检测MySQl
    改进MySQL Order By Rand()的低效率
    RDS for MySQL查询缓存 (Query Cache) 的设置和使用
    RDS For MySQL 字符集相关说明
    RDS for MySQL 通过 mysqlbinlog 查看 binlog 乱码
    RDS for MySQL Mysqldump 常见问题和处理
    RDS for MySQL Online DDL 使用
    RDS MySQL 表上 Metadata lock 的产生和处理
    RDS for MySQL 如何使用 Percona Toolkit
    北京已成为投融资诈骗重灾区:存好骗子公司黑名单,谨防上当!
  • 原文地址:https://www.cnblogs.com/weicyNo-1/p/11013395.html
Copyright © 2011-2022 走看看