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)一些文档的替换
    在开发中我们可能会有一些文档之类的在代码中,但是在迭代后可能会没有用,我们可以删除这些东西来减小体积。 

  • 相关阅读:
    delphi.数据结构.链表
    delphi.指针.PChar
    delphi.指针.应用
    delphi.memory.分配及释放---New/Dispose, GetMem/FreeMem及其它函数的区别与相同
    Delphi系统变量:IsMultiThread对MM的影响
    安装文件制作工具Wix概念快速入门
    [转]JUnit-4.11使用报java.lang.NoClassDefFoundError: org/hamcrest/SelfDescribing错误
    Xiaohe-LeetCode 288 Unique Word Abbreviation
    Xiaohe-LeetCode 100 Same Tree
    Xiaohe-LeetCode 237 Delete Node in a Linked List
  • 原文地址:https://www.cnblogs.com/weicyNo-1/p/11013395.html
Copyright © 2011-2022 走看看