近期正处于一段工做空白区,也想着学习学习一下项目优化,因此就本身的项目出手,一步一步地优化项目。html
项目自己首先划分功能区以Page
、Core
、App
划分python
Page
存储应用的模块,包含首页
、我的中心等
,每一个模块下再以Controller
、View
、Model
划分Core
存储着一些与项目业务、界面无关的类,包括分类
、宏定义
、封装的请求基类
等App
则存储着一些与项目相关的类,包括API
、Base基类
等这里使用了python
脚本 脚本地址 找出项目中未使用的图片,结果不是很是准确,可是能够自行判断(存在图片使用是根据服务端返回显示的状况等)
git
unUseImage.py
文件python unUseImage.py
使用后会在路径里输出文件:
这里使用工具 ImageOptim ,点击连接下载 将项目图片拖入优化便可 优化结果: github
这里推荐使用LinkMap,能够知道项目中各个类的大小,以权衡是否有替换方案 数组
安装fui性能优化
sudo gem install fui -n /usr/local/bin
复制代码
到项目中使用bash
fui find
复制代码
便可找出未引用的类,自行判断删除便可 #####优化前与优化后的ipa
包大小对比 iphone
使用instruments leaks
检测 打开:工具
CellTree
、下方筛选在性能优化中一个最具参考价值的属性是FPS:全称Frames Per Second,其实就是屏幕刷新率,苹果的iphone推荐的刷新率是60Hz,也就是说GPU每秒钟刷新屏幕60次,这每刷新一次就是一帧frame,FPS也就是每秒钟刷新多少帧画面。静止不变的页面FPS值是0,这个值是没有参考意义的,只有当页面在执行动画或者滑动的时候,FPS值才具备参考价值,FPS值的大小体现了页面的流畅程度高低,当低于45的时候卡顿会比较明显。性能
Core Animation
来检测,注:需使用真机打开: 一、Product -> Profile -> Core Animation 二、启动应用 三、滑动查看FPS值
这个选项是检测哪里发生了图层混合,先介绍一下什么是图层混合?不少状况下,界面都是会出现多个UI控件叠加的状况,若是有透明或者半透明的控件,那么GPU会去计算这些这些layer最终的显示的颜色,也就是咱们肉眼所看到的效果。例如一个上层Veiw颜色是绿色RGB(0,255,0),下层又放了一个View颜色是红色RGB(0,0,255),透明度是50%,那么最终显示到咱们眼前的颜色是蓝色RGB(0,127.5,127.5)。这个计算过程会消耗必定的GPU资源损耗性能。若是咱们把上层的绿色View改成不透明, 那么GPU就不用耗费资源计算,直接显示绿色。 若是出现图层混合了,打开Color Blended Layers选项,那块区域会显示红色,因此咱们调试的目的就是将红色区域消减的越少越好。那么如何减小红色区域的出现呢?只要设置控件不透明便可。
运行应用 在模拟器中找到:
label.layer.masksToBounds = YES
,由于当UILabel的内容为中文时,label实际渲染区域要大于label的size,最外层多了一个sublayer,若是不设置第二行label的边缘外层灰出现图层混合的红色,所以须要在label内容是中文的状况下加第二句。单独使用label.layer.masksToBounds = YES
是不会发生离屏渲染的注:xib 也能够直接设置 masksToBounds
在控件的:
+
号添加
layer.masksToBounds
打钩便可 优化后的界面:
这个选项能够帮助咱们查看图片大小是否正确显示。若是image size和imageView size不匹配,image会出现黄色。要尽量的减小黄色的出现,由于image size与imageView size不匹配,会消耗资源压缩图片。 选择:
离屏渲染Off-Screen Rendering 指的是GPU在当前屏幕缓冲区之外新开辟一个缓冲区进行渲染操做。还有另一种屏幕渲染方式-当前屏幕渲染On-Screen Rendering ,指的是GPU的渲染操做是在当前用于显示的屏幕缓冲区中进行。 离屏渲染会先在屏幕外建立新缓冲区,离屏渲染结束后,再从离屏切到当前屏幕, 把离屏的渲染结果显示到当前屏幕上,这个上下文切换的过程是很是消耗性能的,实际开发中尽量避免离屏渲染。 触发离屏渲染Offscreen rendering的行为:
运行项目,打开:
在切圆角时,使用了layer.masksToBounds && layer.cornerRadius
这里咱们换一种实现方式,使用贝塞尔曲线画一个边框Layer覆盖在上面即解决了离屏渲染
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:rect byRoundingCorners:UIRectCornerAllCorners cornerRadii:CGSizeMake(cornerRadius, cornerRadius)];
CAShapeLayer *strokeLayer = [CAShapeLayer layer];
strokeLayer.path = maskPath.CGPath;
strokeLayer.fillColor = [UIColor clearColor].CGColor; //内容填充的颜色设置为clear
strokeLayer.strokeColor = kWhiteColor.CGColor; //边色
strokeLayer.lineWidth = 1; // 边宽
[self.layer addSublayer:strokeLayer];
复制代码
网上还有许多方式能够设置圆角:
UIBezierPath + Core Graphics
切圆角UIBezierPath + Core Graphics
覆盖镂空图片在四角 等等 处理后的效果:
程序运行中不免会出现崩溃,这里咱们可使用runtime
尽可能避免一些常见的崩溃错误: #####eg: 给NSArray 替换 objectAtIndex:
方法
+ (void)load {
[NSClassFromString(@"__NSArrayI") swapMethod:@selector(objectAtIndex:) currentMethod:@selector(mq_objectAtIndex:)];
}
- (id)mq_objectAtIndex:(NSUInteger)index
{
if (index >= [self count])
{
return nil;
}
return [self mq_objectAtIndex:index];
}
+ (void)swapMethod:(SEL)originMethod currentMethod:(SEL)currentMethod;
{
Method firstMethod = class_getInstanceMethod(self, originMethod);
Method secondMethod = class_getInstanceMethod(self, currentMethod);
method_exchangeImplementations(firstMethod, secondMethod);
}
复制代码
Load方法替换 objectAtIndex
为 mq_objectAtIndex
,当调用objectAtIndex
时会走到mq_objectAtIndex
,判断是否越界,以此来预防数组越界的crash 其余类像NSDictionary、NSString
也能够自行添加
iOS项目优化还有挺多方面的,包括电池优化、启动优化等等,笔者这里就先优化到这里,若是有需求须要优化的话,会再进行更新,谢谢支持!