美文网首页iOS实践傲视苍穹iOS《Objective-C》VIP专题程序员
UIImageView UIView圆角与性能之间的研究与优化

UIImageView UIView圆角与性能之间的研究与优化

作者: Syik | 来源:发表于2017-07-28 14:31 被阅读1135次

UIImageView UIView圆角与性能之间的研究与优化

设想:

找出直接设置圆角(maskToBounds/clipsToBounds)帧数下降的例子, 
然后利用Runtime的Method Swizzle交换系统的setClipsToBounds方法 
若设置了layer.cornerRadius 且 clipsToBounds = YES, 则clipsToBounds不会设置为YES, 
而是通过各种其他方法设置圆角, 例如:
1.生成一个圆形的CALayer作为UIImageView.layer.mask.
2.异步剪裁图片.
(以上方法均为网络上流传性能优化方法)

场景:

在日历中每一个UICollectionCell增加一个UIImageView并设置圆角

实际:

图为直接设置cornerRadius和maskToBounds属性, 在如此多的圆角图片下,依然是60帧.
手机iPhone6, 系统为iOS10, 网上传的比较多的是iOS9以上png图片不会触发离屏渲染,
所以不会怎么影响性能, 但我换成jpg图片 依然是60帧.
但我还是尝试了一下上面的两种方法, 看是什么作用:
1.生成一个圆形的CALayer作为UIImageView.layer.mask:
帧数明显降低.

2.异步剪裁图片.
正常操作帧数没有异常, 快速滑动, 会在cell的重用上出问题, 帧数明显下降.

以上肉眼观察明显, 并不需要instrument监控.

所以图片真的没必要异步剪裁!
所以图片真的没必要异步剪裁!
所以图片真的没必要异步剪裁!

UIImageView 结论

在百分之九十九的情况下,
放心使用系统自己的maskToBounds/clipsToBounds与cornerRadius吧,
不会有任何性能问题, 
实际上圆角对于安卓都不是事,
iOS缺老生常谈,确实不应该啊.(基于项目不兼容iOS8了)

UIImageView确定了结果, 
但实际上圆角的设置远不是UIImageView,
怎么对UIView设置圆角并且保持较好的性能,
网上爬文也难有一个比较结论性的回答.
再测试一下直接对UIView直接设置圆角.

场景:

依然是日历, 每一个cell中有2个UILabel.

实际:

这次就出问题了, 滑动帧数直接降到15左右

依然按照上面的思路进行优化, 交换方法为setClipsToBounds与layoutSubViews, 
在设置clipsToBounds = YES且layer.cornerRaius > 0的情况下,
layoutSubViews中进行优化:

1.生成一个圆形的CALayer作为UIImageView.layer.mask:
帧数明显更低了, 所以这种方法在网上流传简直是害人...平均帧数不及10
2.异步剪裁图片.
因为UIView本身并不是UIImage的容器, 所以不太容易直接放, 
新增一个UIImageView盖在上面, 在异步绘制出当前cell, 并放入.
结果喜人, 帧数提高到了60帧附近了.
这里又有之前的前辈教导的常识:CALayer比UIView更轻量, 
所以不需要响应交互的地方用CALayer可以大幅提高性能.
将UIImageView换为CALayer, 并将图片放入contents.
结果实际上并没有更好, 也许是帧数已经快到极限了.

UIView 结论

依然是, 屏幕里圆角数量不多的情况下(15-), 不太需要想办法, 大胆用吧.
屏幕圆角非常多, 可以使用我写的这种方法, 但限制其实也挺多的,
背景色必须是纯色.
当然最好的方法肯定是UI直接把阴影与圆角剪裁给你, 直接用,
虽然会有图层混合运算, 但是其实对性能影响很微妙.

https://github.com/syik/UIImageView-ZJRadius

喜欢的话给个喜欢或者关注一下 3Q~

相关文章

网友评论

  • 89ea79807689:相比在layer上操作cornerRadius,maskTobounds来实现圆角,用绘制比较好吧,性能应该要高于前者。
    Syik:@Clownhu 文中已经有结论了, 如果圆角很少,没必要异步剪裁,如果圆角很多,性能也没有提升,特殊情况反而会带来问题。
  • RiberWang:cell的圆角设置会有问题吗
    Syik:@RiberWang 因为他们是"老"程序员... 试一试就知道了 iPhone6以上 一个界面设置个20个圆角都不会太影响, 性能优化主要是GPU负担不起转移到CPU上, 在很早的时候性能确实有限, 这两年性能已经有很大的突破了.. 话说回来, 虽然不怎么影响, 但是原理得知道, 不然你说不过他 是吧.
    RiberWang:@Syik 好多人都说这样不好 影响性能
    Syik:@RiberWang 直接设置吧
  • 笑医久久:我一开始就觉得异步剪裁应该不会有多大问题,就想看看你的代码,结果只有两个分类,我索性就自己写了一个demo。实测,异步剪裁也能到55,使用layer.mask的方式会卡顿是因为有alloc操作,不知道你为什么说异步剪裁也会出现帧数下降?
    Syik:@笑医久久 大量圆角快速快速快速滑动会有一点点影响,而且图像比较大的话内存也会变多,但是大量圆角也只有这个办法了,原生的方法会更卡
  • 未来行者:我记得是9之后,优化过这个问题,只不过目前ios8还有人在用而已
    Syik:@未来行者 iOS9 UIImageView设置png图片的圆角不会产生离屏渲染,这是原话。实际是不用考虑。
  • hexiaoxiao:肯定不会用mask的吧,,这个比clipsToBounds圆角性能更差.
    Syik:是啊, 但你可以试试搜一下, 说这个是高性能圆角优化的文章比比皆是...

本文标题: UIImageView UIView圆角与性能之间的研究与优化

本文链接:https://www.haomeiwen.com/subject/hhzxlxtx.html