美文网首页
iOS优化IPA包体积大小

iOS优化IPA包体积大小

作者: love_night | 来源:发表于2020-12-27 00:16 被阅读0次

    随着项目的不断迭代,我们APP的体积也越来越大,这势必造成下载的资源浪费,同时也给新用户下载带来流量的浪费,因此我们决定开始优化我们的IPA的体积,方便用户下载的同时,也剔除代码中的冗余资源和文件,方便后续的持续迭代。

    一:资源部分

    1.1 删除项目中无用资源

    由于项目随着时间的推移,势必项目中会存在一些资源(图片,视频,音频等等)已经弃用或者被替换,但是没有及时去删除,因此我们首先删除这些无用资源。我们采用LSUnusedResources工具。


    QQ20201225-171355.png

    注意:必须勾选Ignore similar name 选项,去除相似命名规范的文件,防止这些文件被引用,但是在无任何检查的情况下被删除。

    1.2 删除项目中1X的图片资源

    iOS适配中,图片资源是展示原则:

    1X 作用于3GS手机,手机的像素320*480,一个点为一个像素
    2X iPhone4开始,尺寸为320x480,但是像素为640x960,即一个点为2个像素,所有需要2X的图片才可以保证页面不失真
    3X iPhone6 plus开始,尺寸为414x736,像素为1242x2208,即一个点3个像素,所以需要3X的图片才能保证页面显示良好

    作为iPhone4之前的手机,市场占有率基本上可以忽略不计。因此,我们完全有必要删除其中1x的图片资源。

    二:压缩资源文件

    2.1 压缩图片资源

    使用无损压缩,例如 ImageOptimpngquant命令tinypng 等工具,如果涉及有损压缩最好要求设计介入进行资源检查。

    本次使用ImageOptim对工程中几乎所有的图片做了一次压缩。在压缩过程中,我们发现,大部分图片都能被压缩到原来的70%左右,个别图片能获得更高的压缩比。但是打包测试后,发现IPA包的大小基本上没有任何变化。

    最后在查阅了Xcode打包对于图片的资源的处理发现,在打包过程中,有一个步骤叫做compile asset catalog。在这个步骤中,Xcode会自行对png图片作压缩,并且会压缩成能够快速读取渲染的格式。我们的项目经过ImageOptim的压缩后,在compile asset catalog的过程中,Xcode会用自己的算法重新压缩,而这个”重新压缩“的过程,很可能把我们之前的压缩给覆盖。

    经过测试,此类压缩基本上对后续的包体积无任何影响,因此查找其他的压缩方案。

    2.2 采用Webp压缩图片资源

    Webp 是由 Google 推出的图片格式,有损压缩模式下图片体积只有 jpeg 格式的 1/3,无损压缩也能减小 1/4,可以使用 cwebp 进行格式压缩转换,目前 SDWebImage、Kingfisher 都用支持该格式解析的拓展。进过测试发现压缩还是非常有效的。

    从项目中随便取2张图片,进行压缩试验:

    iOS优化IPA包体积大小

    随着项目的不断迭代,我们APP的体积也越来越大,这势必造成下载的资源浪费,同时也给新用户下载带来流量的浪费,因此我们决定开始优化我们的IPA的体积,方便用户下载的同时,也剔除代码中的冗余资源和文件,方便后续的持续迭代。

    一:资源部分

    1.1 删除项目中无用资源

    由于项目随着时间的推移,势必项目中会存在一些资源(图片,视频,音频等等)已经弃用或者被替换,但是没有及时去删除,因此我们首先删除这些无用资源。我们采用LSUnusedResources工具。

    注意:必须勾选Ignore similar name 选项,去除相似命名规范的文件,防止这些文件被引用,但是在无任何检查的情况下被删除。

    1.2 删除项目中1X的图片资源

    iOS适配中,图片资源是展示原则:

    1X 作用于3GS手机,手机的像素320*480,一个点为一个像素
    2X iPhone4开始,尺寸为320x480,但是像素为640x960,即一个点为2个像素,所有需要2X的图片才可以保证页面不失真
    3X iPhone6 plus开始,尺寸为414x736,像素为1242x2208,即一个点3个像素,所以需要3X的图片才能保证页面显示良好

    作为iPhone4之前的手机,市场占有率基本上可以忽略不计。因此,我们完全有必要删除其中1x的图片资源。

    二:压缩资源文件

    2.1 压缩图片资源

    使用无损压缩,例如 ImageOptimpngquant命令tinypng 等工具,如果涉及有损压缩最好要求设计介入进行资源检查。

    本次使用ImageOptim对工程中几乎所有的图片做了一次压缩。在压缩过程中,我们发现,大部分图片都能被压缩到原来的70%左右,个别图片能获得更高的压缩比。但是打包测试后,发现IPA包的大小基本上没有任何变化。

    最后在查阅了Xcode打包对于图片的资源的处理发现,在打包过程中,有一个步骤叫做compile asset catalog。在这个步骤中,Xcode会自行对png图片作压缩,并且会压缩成能够快速读取渲染的格式。我们的项目经过ImageOptim的压缩后,在compile asset catalog的过程中,Xcode会用自己的算法重新压缩,而这个”重新压缩“的过程,很可能把我们之前的压缩给覆盖。

    经过测试,此类压缩基本上对后续的包体积无任何影响,因此查找其他的压缩方案。

    2.2 采用Webp压缩图片资源

    Webp 是由 Google 推出的图片格式,有损压缩模式下图片体积只有 jpeg 格式的 1/3,无损压缩也能减小 1/4,可以使用 cwebp 进行格式压缩转换,目前 SDWebImage、Kingfisher 都用支持该格式解析的拓展。进过测试发现压缩还是非常有效的。

    从项目中随便取2张图片,进行压缩试验:

    cwebp -lossless baby_info@3x.png -o ~/Desktop/new.webp
    Saving file '/Users/wyz/Desktop/new.webp'
    File:      baby_info@3x.png 3KB
    Dimension: 51 x 51
    Output:    2000 bytes (6.15 bpp)
    Lossless-ARGB compressed size: 2000 bytes
      * Header size: 193 bytes, image data size: 1781
      * Precision Bits: histogram=3 transform=3 cache=9
      
    cwebp -lossless baby_info@2x.png -o ~/Desktop/new2.webp
    Saving file '/Users/wyz/Desktop/new2.webp'
    File:      baby_info@2x.png 2KB
    Dimension: 34 x 34
    Output:    986 bytes (6.82 bpp)
    Lossless-ARGB compressed size: 986 bytes
      * Header size: 547 bytes, image data size: 414
      * Lossless features used: PALETTE
      * Precision Bits: histogram=5 transform=5 cache=0
      * Palette size:   235
    

    有了这个工具,确实可以大大的压缩项目中的图片资源。我们从上面的代码中看到,3K的图片可以压缩成2K,2K的最后也可以压缩不到1K,确实效率很高。项目中展示压缩过得图片,基本上看不出有任何变化,证明此压缩方案可行。

    尝试删除项目中asset catalog除了启动图和icon的图标外的其他图片,经过压缩从10M左右减少到7M左右,所以看起来效果还是不错的,但是项目中图片访问只能通过bundle中来获取,这个和从asset catalog中读取图片的效率就有待商榷,毕竟asset catalog是Apple推荐的图片资源管理模式。

    尝试打包在6和plus上安装时发现,安装包大小竟然一样的大小,并且在6上面的大小和优化之前基本上没有什么变化,甚至比之前的还大,显然这不是我们想要的效果。

    最后查看App Store的APP在下载过程中发现,Apple会在设备下载APP是,会根据设备类型,下载IPA中不同的资源,即asset catalog中的图片资源,设备支出2X的图片,它也只会选择asset catalog中所有的2X的图片进行下载,所以我们废弃asset catalog使用后,所有的图片都进行了下载,比之前的包大也就说的过去了,因此看起来这种方法也不可取。

    但是作为图片压缩一种相当不错的方式,我们完全可以用在网络图片的下载中使用。

    2.3 单色图标使用tint color

    Apple在iOS7推出的功能,我们可以读取一个图标,然后给它赋予一个color值,在手机屏幕上它就能显示出相应的效果。tint color适用于对单色图标进行着色,相比于其他精简图标的解决方案,tint color方便、可靠、拥有原生支持。

    因此,花费一些时间排查一下简单的相同样式图片,采用tint color的方式来填充颜色,从而起到优化IPA包的效果。

    2.4 资源考云端下载

    Apple从iOS 9开始引入了On Demand Resource功能,即一部分图片可以被放置在苹果的服务器上,不随着app的下载而下载,直到用户真正进入到某个页面时才下载这些资源文件。

    但是考虑到项目最低支持的版本,此方法只能放弃。

    三:删除重复文件

    我们采用fdupes工具。它是通过对比文件的MD5签名,以及逐字节比较文件来识别重复内容,fdupes有各种选项,可以实现对文件的列出、删除、替换为文件副本的硬链接等操作。
    文件对比:大小对比 > 部分 MD5 签名对比 > 完整 MD5 签名对比 > 逐字节对比

    安装fdupes工具,然后进行测试。

    // 进入项目文件下的所有资源文件夹,找出所有重复文件,导出到txt中查看
    fdupes -Sr StoryToy > ~/Desktop/123/123.txt
    
    查看项目中的重复文件
    386 bytes each:
    StoryToy/Bindings/addDevice/RTBindingReadyViewController.h
    StoryToy/Bindings/addDevice/RTBindingChoiceListViewController.h
    
    341 bytes each:
    StoryToy/RooboMember/VipRights/View/RBVipRightSectionReusableView.h
    StoryToy/CloudResource/RooboMember/VipRights/View/RBVipRightSectionReusableView.h
    
    1869 bytes each:
    StoryToy/RooboMember/VipRights/View/RBVipRightCollectionViewCell.m
    StoryToy/CloudResource/RooboMember/VipRights/View/RBVipRightCollectionViewCell.m
    
    ......
    

    可以看出我们确实查到了一些重复文件。

    四:编译相关

    4.1 Valid Architectures

    设置生成IPA包所包含的支持架构,如果项目中还包含32位,armv7及之前的架构,但是我们项目现在已经不支持的可以考虑删除。

    4.2 App Thinning

    WWDC2015 发布会上首次介绍了 App Thinning,并在 iOS9 开始应用。严格来说App Thinning不会让安装包变小,但用户安装应用时,苹果会根据用户的机型自动选择合适的资源和对应CPU架构的二进制执行文件(也就是说用户本地可执行文件不会同时存在 armv7 和 arm64),减少下载流量和安装占用空间。


    QQ20201226-202726@2x.png

    五:Framework优化

    引入三方Framework时,会包含多个指令集,我们可以手动移除不需要的指令集。或者查找只包含我们项目指令集的framework。

    首先我们需要了解不同指令集对应的设备类型:

    armv7 iPhone4s之前,iPad,iPad2,iPad3(The New iPad),iPad mini,iPod Touch 3G
    armv7s iPhone5,iPhone5C,iPad4(iPad with Retina Display)
    arm64 iPhone5s之后的机型,iPad Air,iPad mini2(iPad mini with Retina Display)等
    x86_64 模拟器64位处理器,Mac应用
    I386 模拟器32位处理器,Mac应用

    例如我们项目中使用的音频格式转换功能中使用的libopencore-amrnb.a的静态库,他其中包含了所有的指令集,而对于大多数移动端 App,只需要 armv7,armv7s 和 arm64 指令集就足够了。

    Architectures in the fat file: /Documents/work/rtoy/ios/RToyAPP/StoryToy/StoryToy/Wechat/RTPlayer/opencore-amr/lib/libopencore-amrnb.a are: i386 x86_64 armv7 armv7s arm64
    

    因此在项目中,我们不需要x86_64,I386 我们只需要保留其他的指令集就可以了。

    //查看静态库的信息
    lipo -info libopencore-amrnb.a
    Architectures in the fat file: libopencore-amrnb.a are: i386 x86_64 armv7 armv7s arm64
    // 抽取单一指令集的静态库
    lipo libopencore-amrnb.a -thin armv7 -output libopencore-amrnbArmv7
    lipo libopencore-amrnb.a -thin armv7s -output libopencore-amrnbArmv7s
    lipo libopencore-amrnb.a -thin arm64 -output libopencore-amrnbArm64
    
    // 查看生成的静态库信息
    ls 
    libopencore-amrnb.a libopencore-amrnbArm64  libopencore-amrnbArmv7  libopencore-amrnbArmv7s libopencore-amrwb.a
    
    lipo -info libopencore-amrnbArmv7
    Non-fat file: libopencore-amrnbArmv7 is architecture: armv7
    
    // 合成完整的静态库
    lipo -create libopencore-amrnbArm64 libopencore-amrnbArmv7 libopencore-amrnbArmv7s -output nb/libopencore-amrnb.a
    
    // 查看新生成的静态库信息
    cd nb;ls
    libopencore-amrnb.a
    lipo -info libopencore-amrnb.a
    Architectures in the fat file: libopencore-amrnb.a are: armv7 armv7s arm64
    

    移除多余的指令集后,静态库大小从 4.8MB 降到 3.3MB,效果还是非常完美的。

    六:结语

    经过本次尝试,IPA包体积都有5%~20%不同程度的减小,当然优化的空间依然巨大。在实际项目瘦身过程中,上面列举的方式不一定都适用。因此对于项目瘦身,还是需要怀着一颗谨慎的心,谨慎检验每一次的尝试。

    相关文章

      网友评论

          本文标题:iOS优化IPA包体积大小

          本文链接:https://www.haomeiwen.com/subject/fmvgnktx.html