卡顿的检测
卡顿时间比
婚恋系统开发卡顿的检测,我们可以使用 instrument
的Animation Hitches
来检测。
在Apple
的官方建议中,使用卡顿时间比
来衡量卡顿的严重等级的。
如果 1s
内的卡顿时间超过10ms
,属于严重卡顿
,需要着重解决。
Animation Hitches
接下来,我们先对我们的UITableView
的滑动进行卡顿分析,在真机上运行婚恋系统,查看结果:
运行结果特别差:有大量的严重卡顿
,有一些卡顿达到了290ms/s
。
Time Profile
我们点击Time Profile
一览,查看此时婚恋系统开发的函数调用栈
,将系统调用筛选出去
我们找到婚恋系统开发的主线程调用栈,查看其使用的时间占比
由分析可知:在 cellforRow
方法的 model.setter
方法中,存在大量的耗时操作,在 提交阶段
产生了延时
,导致卡顿。可以使用此方法,依次查看每处卡顿的函数调用栈,来分析提交阶段的卡顿
。
Show Optimization Opportunities
另一方面,我们也可以使用Xcode
检测App的性能,在Xcode 12
中,点击 Debug View Hierarchy
,然后在 Editor
选项中,默认勾选了Show Optimization Opportunities
,Xcode
会帮我们检测,App在运行过程中,一些优化的建议。
这段话,告诉我们,我们通过使用了 CAShapeLayer
作为mask
,来实现圆角
效果,建议我们使用系统的 cornerRadius
来实现。
为什么使用mask
不行呢?
在Editor
选项中,选中Show Layers
:
婚恋系统开发使用 CAShaperLayer + mask
的形式来制作圆角,会造成离屏渲染
。在cell的滚动过程中,会有 成百上千
个离屏渲染
,提交到渲染服务器,会产生卡顿。
Color Off-screen Rendered
在 模拟器中,打开Debug -> Color Off-screen Rendered
,可以检测离屏渲染,离屏渲染的视图
会标记为黄色
。
从模拟器中,我们可以看出,容器视图造成了离屏渲染。
列表优化
圆角优化
1,在iOS13
之后,可以使用系统的ApIcornerRadius
和cornerCurve
。
view.layer.cornerRadius = 22
view.layer.cornerCurve = .continous
2,对于UILabel和UIButton
,婚恋系统开发可以直接使用 cornerRadius
。
label.layer.cornerRadius = 22
3,重写view
的-drawRect:
的方法,使用Core Graphic
绘制圆角
- (void)drawRect:(CGRect)rect {
[super drawRect:rect];
UIBezierPath *p = [UIBezierPath bezierPathWithRoundedRect:rect byRoundingCorners:(_bottomLeftRadius?UIRectCornerBottomLeft:0)|(_bottomRightRadius?UIRectCornerBottomRight:0)|(_topLeftRadius?UIRectCornerTopLeft:0)|(_topRightRadius?UIRectCornerTopRight:0) cornerRadii:CGSizeMake(_singleCornerRadius, 0.f)];
CGContextRef c = UIGraphicsGetCurrentContext();
CGContextAddPath(c, p.CGPath);
CGContextClosePath(c);
CGContextClip(c);
CGContextAddRect(c, rect);
CGContextSetFillColorWithColor(c, _bgColor.CGColor);
CGContextFillPath(c);
}
将GPU
的操作,转移到 CPU
上,均衡GPU和CPU
的操作。
数据源预加载
在 iOS 10
之后,可以使用 UITableViewDataSourcePrefetching
代理方法,对数据进行预加载
func tableView(tableView: UITableView, prefetchRowsAt indexPaths: [IndexPath]) {
let needFetch = indexPaths.contains { $0.section >= self.layoutArray.count - 1 }
if needFetch {
// 1.满足条件进行翻页请求
}
}
数据源预处理
在网络请求完数据后,对数据进行预处理,将 NSAttributeString
的初始化逻辑
和数据源逻辑
处理放在异步子线程
中。
如果不使用AutoLayout
,可以在数据源预处理阶段,计算好子视图的frame。
优化 cellForRow 方法
将cell
的背景色处理和事件绑定等事件,移至willDisplayCell
中。在cellforRow
方法中,不做逻辑处理,只做简单的赋值操作。
AutoLayout
如果cell
采用了AutoLayout
布局,应注意两个问题:
-
1,应解决
约束冲突
问题,在动态操作约束值,会经常报这个错误,约束冲突时,约束engin
会产生大量的CPU
计算。解决此类问题,可以从两个方面入手:
1,分析约束是否合理。 2,可以尝试改变约束的Priority
。
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x600003b0cc80 DBRadiusView:0x7fb9d80b0e20.bottom == UIImageView:0x7fb9d80b59c0.bottom + 8>
- 2,避免
约束流失
问题,避免在cell
复用过程中反复的删除约束
和新增约束
避免视图删除
婚恋系统开发如果需要消息视图,避免将视图从cell中删除,尽可能的使用hidden
属性。
结果对比
婚恋系统开发做完这些优化后,我们来看下卡顿的分布情况
最大的卡顿时间比
为32.84ms/s
,在列表滑动时,没有高等级
的卡顿
,这样婚恋系统开发就达到了一种比较理想的状态。
声明:本文由云豹科技转发自Bel李玉博客,如有侵权请联系作者删除