iOS包瘦身我的思路在于以下几点:
之前某些版本里面改了UI或者某些页面不用了,导致有一些图片一直遗留下来忘记删掉,可以使用工具LSUnusedResources去查找项目中的多余资源。关于使用的方法链接里也有详细的介绍,这里就不赘述了。(这里有一些坑,扫描出来的无用图片有可能被使用了,但脚本不能识别,例如某些图片的名字是由后台传过来的,这样识别不了。)
对于资源文件进行压缩的话要和相关同事做好沟通,例如图片不能压缩得太过模糊导致ui根本不收货。
图片压缩工具有很多,这里介绍两个好用的:
【建议】:对于较大尺寸的图片,可以和设计沟通,在不失真和影响效果的前提下,使用TinyPNG进行压缩;较小尺寸的图片,建议使用ImageOptiom。
进行图片压缩的时候项目使用.xcassets管理,而且图片文件结构是这样的,如果我要一个一个更换图片的话估计会崩溃。
所以得使用批量压缩更换图片的脚本,可以参考这篇文章。
修改完脚本里面的参数后,控制台cd到脚本目录,python tinyPng.py运行脚本,然后等待图片复制(数量大的话挺久的)。
图片资源的导入方式有如下几种:
1. Assets.xcassets。
2. CreateGroup
3. CreateFolderRefences
【说明】:蓝色文件夹只是将文件单纯的创建了引用,这些文件不会被编译,所以在使用的时候需要加入其路径。
4. Bundle(包)
对于上面这几种不同的导入方式,会对打出的包的大小有影响么?
经过测试得知:CreateGroup、CreateFolderRefences两种方式打出来的包,图片都会直接放在.app文件中,所以打包前后,图片的大小不会改变。而加入到Assets.xcassets中的方法则不同,打包后,在.app中会生成Assets.car文件来存储Assets.xcassets中的图片,并且文件大小也大大降低。
对于某一些资源来说是不是必须要导入到工程中?或者说,有没有别的办法替代。
对于资源的必要性这只是其中几点,肯定还有很多办法继续优化。
.o是我们写的xxx.m、xxx.h经过编译后的可执行文件,每一个.o文件的大小可以通过linkmap文件计算出来。
首先我们设置xcode的Write Link Map File选项。XCode -> Project -> Build Settings -> 搜map -> 把Write Link Map File选项设为yes,并指定好linkMap的存储位置。默认地址是在~/Library/Developer/Xcode/DerivedData/xxx-xxx-fwtuexpkzxsfkjaootcqwizogrhf/Build/Intermediates/xx-xxx.build/Debug-iphonesimulator/xxx-xxx.build/xxx-xxx-LinkMap-normal-x86_64.txt(文件路径顺序基本一致,文件名会有所不同,自行查看)。
拿到linkmap后可以通过一些脚本工具去进行分析,我用的是这个小工具。分析过后可以看到类似的界面,这样就可以看到各个文件的大小了。
对于可执行文件的优化其实就是优化我们所写的代码,分为一下几点:
项目经过不断的迭代,有一些类,一些代码已经不会被使用到了,找出它们并删除掉。这里也提供一个工具,可以用来找无用的类。
对一些常用控件进行封装(共用弹窗等),可以复用的代码块做成工具类减少复制黏贴的代码。使用一些基类,可以把一些重复的代码丢到基类里面。对于一些不怎么改动,而且在项目中也比较稳定的功能模块,可以选择打包成静态库的形式。这样既可以提高复用,又可以减少编译时间。以上只是很少的一部分,办法还有很多。
这个没什么好说的,试着重构代码吧。
把一些重复功能的第三方库删除掉,或者只用到很少功能的第三方去掉,自己用原生代码实现。某些第三方库我们只用到部分功能,可以对他作出精简,例如有些IM第三方会提供UI模块,而这个我们完全可以自己写。
对于代码的优化,感觉优化效率比较低,对于包size的减少没有很明显的改变,远没有优化资源来得爽利,而且优化代码需要很熟悉相关的业务,不然改着改着出现一堆bug。这也是考验重构能力的地方,要做的东西有很多,效果也不明显,但是不能放弃治疗。
关于编译优化这一块,说起来是一个很大的东西,而且我也是只看了些皮毛。想要做好编译优化这一块,感觉需要学习的东西有非常多。所以只能简单说说我关于编译这一块的一些理解,有理解错误的地方欢迎指正。
想要对编译做出优化,那么我们就先要了解我们平时command+B的时候Xcode做了些什么。其实当我们按下command+B或者command+R的时候Xcode就会去执行一堆clang的命令,对我们的代码进行编译,也可以在Xcode中看到具体执行了什么命令,然后结果是怎样的(成功、错误、警告等等)。对于Xcode的编译我们也可以手动通过clang命令一步一步的去拆分,看看每一步生成的是什,具体可以跟着这篇文章去做。
说到clang,那就不可避免的要了解到LLVM。LLVM是什么?
LLVM是构架编译器(compiler)的框架系统,以C++编写而成,用于优化以任意程序语言编写的程序的编译时间(compile-time)、链接时间(link-time)、运行时间(run-time)以及空闲时间(idle-time),对开发者保持开放,并兼容已有脚本。
LLVM计划启动于2000年,最初由美国UIUC大学的Chris Lattner博士主持开展。2006年Chris Lattner加盟Apple Inc.并致力于LLVM在Apple开发体系中的应用。Apple也是LLVM计划的主要资助者。
目前LLVM已经被苹果IOS开发工具、Xilinx Vivado、Facebook、Google等各大公司采用。
引用百度一段对于LLVM的一段介绍,我们可以认为LLVM是一个完整的编译器架构,也可以认为它是一个用于开发编译器、解释器相关的库。
LLVM分为前端和后端两个部分。其中前端部分接受不同的语言代码,如OC、C++等。对不同的语言进行词法、语法、语意分析等,然后生成中间代码(IR code),其中IR代码可以经过多个优化流程(Pass),对的这个叫Pass的东西就是我们想要的编译优化!通过编写不同的Pass可以对编译的时间、包大小进行优化。然而我并不会写......感觉这个东西有点高级,想要做这个还是有点困难的,苹果有做相关的优化,可以通过设置Xcode的BuildSettings选项来配置。Pass走完以后会来到后端,后端会根据IR代码生成符合各个CPU架构的ipa包。
关于编译相关的东西由于篇幅有限,就写了一些自己的理解,也不知道有没有错误。看了一些资料,也不能说百分百的理解。然后如果对这方面有兴趣的推荐下面一些博客,或者文章。都是我之前看的,看得也比较零散。
iOS编译过程的原理和应用
关于Xcode编译性能优化的研究工作总结
上面最后一篇文章有详细介绍如何配置Xcode的BuildSettings选项,也对各个选项做了相关的解析。