底层架构 端口映射 jetbrains PaddleHub function go uiviewcontroller 传智播客python ppt视频教程下载 jquery通过class获取元素 oracle无效的列索引 matlab中log函数 mysql数据库名称 mysql安装后怎么使用 spring源码下载 python for循环 普通话网上报名 python集合 python的开发工具 python字符串匹配 javasubstring java数组最大值 获取当前时间java java线程死锁 音频频谱分析软件 mounted 摩斯电码翻译器 万能低格工具 摩斯密码翻译 神剪辑教程 max电池容量 快捷精灵 微信彩色字 脚本错误怎么解决 特战英雄辅助 vbs代码 cad文件 内存条有什么用 点状字体 dll注入器
当前位置: 首页 > 学习教程  > 编程语言

iOS 启动优化和安装包瘦身

2020/11/24 9:54:36 文章标签: 测试文章如有侵权请发送至邮箱809451989@qq.com投诉后文章立即删除

iOS 启动优化和安装包瘦身 1 启动优化 在iPhone的启动方式中,分为冷启动和热启动两种方式: 1、冷启动(Cold Launch):从零开始启动APP ,需要系统新创建一个进程进行启动,这是一次完整的启动&a…

iOS 启动优化和安装包瘦身

1 启动优化

在iPhone的启动方式中,分为冷启动和热启动两种方式:

  • 1、冷启动(Cold Launch):从零开始启动APP ,需要系统新创建一个进程进行启动,这是一次完整的启动;
  • 2、热启动(Hot Launch):APP已经在内存中,在后台存活着,再次点击直接打开

我们一般说的启动优化是指: 冷启动时的优化;

要达到优化启动的目的,就需要知道在APP启动的时候,有哪些流程,做了哪些事情;

APP的启动过程是从:点击应用icon图标,到启动图展示,再到首页展示完成的过程:

打印查看启动时间:

通过添加环境变量可以打印出APP的启动时间分析(Edit scheme -> Run -> Arguments)

1、将DYLD_PRINT_STATISTICS设置为1

image.png

打印如下:
image.png

2、 如果需要更详细的信息,那就将DYLD_PRINT_STATISTICS_DETAILS设置为1

image.png

打印如下:

image.png

1.1 Main()函数执行前

dyld(dynamic link editor):动态链接器,用来装载Mach-O文件(可执行文件、动态库等)

  • dyld 加载可执行文件mach-o文件到内存中

    • 装载APP的可执行文件,同时会递归加载所有依赖的动态库
    • 当dyld把可执行文件、动态库都装载完毕后,会通知Runtime进行下一步的处理
  • runtime加载类和分类:

    • 调用map_images进行可执行文件内容的解析和处理
    • 在load_images中调用call_load_methods,调用所有Class和Category的+load方法
    • 进行各种objc结构的初始化(注册Objc类 、初始化类对象等等)
    • 调用C++静态初始化器和__attribute__((constructor))修饰的函数

所有初始化工作完成以后,dyld会调用main函数,接下里就是UIApplicationMain函数的流程

1.1.2 启动优化:

  • 1、dyld

    • 减少动态库、合并一些动态库(定期清理不必要的动态库)
    • 减少Objc类、分类的数量、减少Selector数量(定期清理不必要的类、分类)
    • 减少C++虚函数数量
    • Swift尽量使用struct
  • 2、runtime

    • 用+initialize方法和dispatch_once取代所有的
    • attribute((constructor))、C++静态构造器、ObjC的+load
  • 3、main

    • 在不影响用户体验的前提下,尽可能将一些操作延迟,不要全部都放在finishLaunching方法中
    • 按需加载

2. 安装包ipa瘦身

官方 App Thinning

App Thinning 是由苹果公司推出的一项可以改善 App 下载进程的新技术,主要是为了解决用户
下载 App 耗费过高流量的问题,同时还可以节省用户 iOS 设备的存储空间。

现在的 iOS 设备屏幕尺寸、分辨率越来越多样化,这样也就需要更多资源来匹配不同的尺寸和分 辨率。 同时,App 也会有 32 位、64 位不同芯片架构的优化版本。如果这些都在一个包里,那 么用户下载包的大小势必就会变大。

App Thinning 会专门针对不同的设备来选择只适用于当前设备的内容以供下载。比如:iPhone 6 只会下载 2x 分辨率的图片资源,iPhone 6plus 则只会下载 3x 分辨率的图片资源。

2.1、使用Asset

  • 使用Asset,将图片区分,对应的2X图片和3X图片,在上传appStore以后会做不同的变体,减少下载包的大小

image.png

例如我现在的项目,由于是老项目,所有的图片都是直接放在工程中的,所以打包的时候没有区分设备,都会直接打包的app包中;

如果使用了现在的Asset,将2x图和3x图区分开来,在appstore下载App的时候,会根据设备,只下载对应的图片,如果使用的是2x设备则只下载2x的图片,3x的设备只下载3x的图片;

这样就会减小从appstore下载时App包的大小。

2.2、删除无用的图片资源

项目中如果迭代过很多版本,图片资源就会很多,需求在更新的同时,所以可能会有很多无用的图片;

所以要使用一定的方法找到项目中不用的图片,并剔除掉;

  1. 通过 find 命令获取 App 安装包中的所有资源文件,比如 find /Users/daiming/Project/ - name。
  2. 设置用到的资源的类型,比如 jpg、gif、png、webp。
  3. 使用正则匹配在源码中找出使用到的资源名,比如 pattern = @"@"(.+?)""。
  4. 使用 find 命令找到的所有资源文件,再去掉代码中使用到的资源文件,剩下的就是无用资源
    了。
  5. 对于按照规则设置的资源名,我们需要在匹配使用资源的正则表达式里添加相应的规则,比如
    @“image_%d”。
  6. 确认无用资源后,就可以对这些无用资源执行删除操作了。这个删除操作,你可以使用
    NSFileManger 系统类提供的功能来完成。
  • 使用第三方软件:LSUnusedResources 链接

image.png

下载完成以后直接运行,然后选择工程所在的目录,直接search,如果项目比较大的话,search的时间也会比较久;

运行以后,直接会显示无用的图片,位置和大小:

image.png

这里选出来的图片需要斟酌一下再去工程里面删除,毕竟也是用正则表达式筛选出来的,有可能会有误差,如果检查过确实没用,就可以直接删除。

2.3、图片资源压缩

删除了无用的图片资源,有用的图片资源其实也是可以优化的,那做法就是将图片进行压缩和解压处理:

对于 App 来说,图片资源总会在安装包里占个大头儿。对它们最好的处理,就是在不损失图片 质量的前提下尽可能地作压缩。目前比较好的压缩方案是,将图片转成 WebP。WebP 是 Google 公司的一个开源项目。

  • 将图片转化成WebP,由于将图片转化成WebP和解压的过程消耗较大,所以可以将图片大于100k的进行转化,其他的小图片不做处理

2.4、删除无用代码

App 的安装包主要是由资源和可执行文件组成的,所以我们在掌握了对图片资源的处理方式后, 需要再一起来看看对可执行文件的瘦身方法。

可执行文件就是 Mach-O 文件,其大小是由代码量决定的。通常情况下,对可执行文件进行瘦 身,就是找到并删除无用代码的过程。而查找无用代码时,我们可以按照找无用图片的思路, 即:

  1. 找出方法和类的全集;
  2. 找到使用过的方法和类;
  3. 接下来,取二者的差集得到无用代码;
  4. 最后,由人工确认无用代码可删除后,进行删除即可。

2.4.1、使用Link Map 统计所有的方法和类

在build settings中搜索link map,然后设为YES;

设置build的输出路径,指定一个文件夹,然后指定输出文件的格式和名字,一般是txt格式,设置好路径后,直接运行,就会在指定的文件夹下生成一个.txt文件;

image.png

打开txt文件,以.o结尾的,都是生成的目标文件,如图:

测试demo我创建了两个类,一个YYPerson,一个YYStudent;

image.png

LinkMap 文件分为三部分:Object File、Section 和 Symbols。如下图所示:
image.png

  • Object File 包含了代码工程的所有文件;
  • Section 描述了代码段在生成的 Mach-O 里的偏移位置和大小;
  • Symbols 会列出每个方法、类、 block,以及它们的大小。

通过 LinkMap ,你不光可以统计出所有的方法和类,还能够清晰地看到代码所占包大小的具体 分布,进而有针对性地进行代码优化。

如果项目较为复杂,分析起来可能会很困难;

可借助第三方工具解析LinkMap文件:链接

运行以后直接打开txt文件:
image.png

这个软件能够清晰的看到有哪些类,以及每个类的大小;

2.4.2、使用 MachOView 统计所有使用过的类

在products中找到.app包,在finder中显示,然后右击显示包内容,找到可执行文件:

image.png

然后使用 MachOView打开可执行文件:

image.png

如图上所示,我们可以看到 objc__selrefs 和 objc__classrefs 以及objc__superrefs 这三个 section。

其实这3个里面都是通过消息机制,objc__msgSend()函数调用过的对象方法,类方法,类,元类等;

但是,这种查看方法并不是完美的,还会有些问题。原因在于, Objective-C 是门动态语言,方法调用可以写成在运行时动态调用,这样就无法收集全所有调用的方法和类。所以,我们通过这 种方法找出的无用方法和类就只能作为参考,还需要二次确认。

2.5 编译器优化

  • Strip Linked Product、Make Strings Read-Only、Symbols Hidden by Default设置为YES

  • 去掉异常支持,Enable C++ Exceptions、Enable Objective-C Exceptions设置为NO, Other C Flags添加-fno-exceptions

利用AppCode检测未使用的代码:菜单栏 -> Code -> Inspect Code

其实启动优化和ipa瘦身,在于平时的很多细节,比如如果是不用的图片,要立即删除,不用的类和方法,也要及时清理,我们一般不删除的原因是怕以后还有可能用到,但是一般都有版本控制,删除了以后再要用可以从之前的版本中去找;

[原文链接](https://www.jianshu.com/p/55222df50138)


本文链接: http://www.dtmao.cc/news_show_400167.shtml

附件下载

相关教程

    暂无相关的数据...

共有条评论 网友评论

验证码: 看不清楚?