我在UIScrollView
中有一个容器视图,该容器视图有几个基于CAShapeLayer
的子视图(大约200个)。每个CAShapeLayer
都包含一个非常简单的CGPath
(一个约10个点的填充多边形)。你可以把它看作一种地图
容器视图本身很大(大约1000x2500点),但我使用transform
属性实现了缩放(我没有使用UIScrollView
实现),所以在小范围内它完全是可见。
在高比例(屏幕上只能看到容器视图的一部分)时,即使在旧硬件上也能很好地滚动,并且滚动顺畅。 但是,在小规模(当大多数容器视图可见时),这会导致旧硬件上的滚动性能非常差(iPhone 4S上为40 fps)。如果我超过200个子视图(这是我想做的事情),即使在更新的硬件上,这也会更糟糕(低至15fps)。
我做了一些分析,但我找不到瓶颈。在滚动期间,我进行了以下测量(平均):
Activity monitor instrument :
CPU : 8%
GPU driver instrument :
Device utilization : 40%
Renderer utilization : 35%
Tiler utilisation : 8%
FPS : 40
以下是我的尝试:
在所有shouldRasterize
上使用正确的rasterizationScale
设置CAShapeLayer
。这让事情变得更糟。
在容器视图的图层上使用正确的shouldRasterize
设置rasterizationScale
。这样可以改进非常小的滚动(当整个容器在scrollView中可见时),但是对于更大的比例来说会更糟糕。仅针对小比例激活光栅化会留下间隙(介于0.5和2.0之间),这两个选项都会导致帧丢失。
仅使用图层而不是视图。没有改善任何事情。
将CATiledLayer
用于容器视图图层。没有改善任何事情。
有什么想法吗? 如果硬件存在限制,我不应该在某个地方看到100%?我还应该剖析什么?
此时我要问的主要问题是如何分析我的应用以及了解造成丢帧的原因的帮助。然后,根据正在发生的事情和可行的事情,我会尝试改进。如果我很幸运的话,我不会要求书中的每一个可能的调整都可以改善一点。
修改
刚刚发现尽管我的应用程序以8%CPU运行,但backboardd
在滚动期间以100%CPU运行。所以瓶颈在于Core Animation渲染服务器!
现在我只需弄明白为什么。也许有太多层...任何人都知道渲染服务器每16ms可以处理的最大层数是多少?我无法找到任何关于此的官方文档。
编辑2
因此,经过一些更多的分析后,它看起来与层数无关。如果我通过组合一些路径(并且因此使用更复杂的路径)将所有形状组合在少量层(大约10个)中,则结果大致相同。滚动期间backboardd
仍然以100%CPU运行
所以我猜这是路径处理/绘图/需要花费时间的东西,不管它们是否有更小/更简单的路径。也许它仅限于点数。我开始认为我无能为力......