我应该关注哪些对性能至关重要的事项?
我希望有一个尽可能多例子的清单,或一份最佳实践清单。
我应该关注哪些对性能至关重要的事项?
我希望有一个尽可能多例子的清单,或一份最佳实践清单。
图形性能最大的瓶颈是离屏渲染和混合 - 它们可能在每个动画帧中发生,导致页面滚动不流畅。
离屏渲染(软件渲染)是指需要在交给GPU之前在软件中绘制(离屏)的情况。硬件无法处理文本渲染以及带遮罩、阴影等高级组合。
以下情况将触发离屏渲染:
任何带有蒙版的图层(layer.mask
)
任何带有layer.masksToBounds
/ view.clipsToBounds
属性,并且其值为true的图层
任何带有layer.allowsGroupOpacity
设置为YES并且layer.opacity
小于1.0的图层
查看更多
任何带有投影阴影(layer.shadow*
)的图层。
如何优化:https://markpospesel.wordpress.com/tag/performance/
任何带有layer.shouldRasterize
属性并且其值为true的图层
任何带有layer.cornerRadius
, layer.edgeAntialiasingMask
, layer.allowsEdgeAntialiasing
属性的图层。
任何带有layer.borderWith
和layer.borderColor
属性的图层。
缺少参考/证明
文本(包括UILabel
、CATextLayer
、Core Text
等任何类型的文本)。
大部分使用 CGContext
在 drawRect:
中绘制的图形都将被呈现在屏幕外,即使是空实现也是如此。
resizableImage
可能导致颜色混合。
在使用可调整大小图片时避免混合图层
任何不是 opaque
且具有 backgroundColor
的层,该颜色的 alpha
小于 1.0
任何 alpha
小于 1.0 的层
任何具有 layer.content
或任何 UIImageView
具有带有 alpha 通道的 UIImage
的层
以下操作将在 UIView 上触发调用 layoutSubviews
:
更改 bounds
,会在相同的视图和父视图上触发
更改 frame
,会在相同的视图和父视图上触发
更改 transform
或 layer.transform
,会在父视图上触发
注:我指的是实际更改值时才会触发
与此相反,以下更改将不会触发调用 layoutSubviews
:center
, layer.position
, layer.zPosition
, layer.anchorPoint
, layer.anchorPointZ
。
参考:https://github.com/hfossli/LayoutSubviewsInconsistency
通常来说,混合渲染比离屏渲染更好。
考虑使用drawRect:
而不是一个带有多个标签和子视图的视图。
在后台队列中绘制到UIImage
或CGImageRef
上。
绘制到一个CGLayer
中(与UIImage
相比,在GPU
上缓存效果更好),并将任何你想要的东西画到其中。
更新,不要: http://iosptl.com/posts/cglayer-no-longer-recommended/
简化你的视图层次结构
重复使用视图 - 不要在滚动时创建和添加新视图
使用纯色opaque
背景的视图
避免将alpha
和layer.opacity
设为小于1.0
启用layer.shouldRasterize
(谨慎使用)。我个人喜欢避免使用它,但在某些情况下它可以更快地执行,因为图层的光栅将被缓存和重复使用。请记住,如果您在频繁更改其内容或子层内容的图层上启用shouldRasterize
,性能会降低,因为iOS将在每次更改时保持光栅化该层。