浅谈iOS复杂列表滑动优化(二)

复杂列表滑动优化(二)

上一篇主要是说了 CPU 相关的优化,这一篇我们讲讲 GPU 的

GPU 工作流水线

GPU的图形(处理)流水线完成如下的工作:(并不一定是按照如下顺序)

顶点处理:
GPU读取描述3D图形外观的顶点数据,并根据顶点数据确定3D图形的形状及位置关系,建立起3D图形的骨架。在支持DX系列规格的GPU中,这些工作由硬件实现的Vertex Shader(定点着色器)完成。

光栅化计算:
显示器实际显示的图像是由像素组成的。
我们需要将上面生成的图形上的点和线通过一定的算法转换到相应的像素点。把一个矢量图形转换为一系列像素点的过程就称为光栅化。
例如,一条数学表示的斜线段,最终被转化成阶梯状的连续像素点。

纹理帖图:
顶点单元生成的多边形只构成了3D物体的轮廓,而纹理映射(texture mapping)工作完成对多变形表面的帖图。
通俗的说,就是将多边形的表面贴上相应的图片,从而生成“真实”的图形。
TMU(Texture mapping unit)即是用来完成此项工作。

像素处理:
这阶段(在对每个像素进行光栅化处理期间)GPU完成对像素的计算和处理,从而确定每个像素的最终属性。
在支持DX8和DX9规格的GPU中,这些工作由硬件实现的Pixel Shader(像素着色器)完成。

最终输出:
由ROP(光栅化引擎)最终完成像素的输出,1帧渲染完毕后,被送到显存帧缓冲区。

总结:
GPU的工作通俗的来说就是完成3D图形的生成,将图形映射到相应的像素点上,对每个像素进行计算确定最终颜色并完成输出。

性能瓶颈

GPU 的主要性能瓶颈产生在:

●纹理的渲染 - 大尺寸纹理渲染
●图层的混合 - 带透明度的多层级视图混合渲染
●离屏渲染 - 圆角,阴影,毛玻璃等效果产生的离屏渲染

检测工具

Xcode -> Debug -> View Debugging -> Rendering

Xcode 自带了渲染服务的检测工具包,包括

Color Misaligned Images

用来标记像素不对齐,设置 Frame 的像素不为整数时,需要转换成整数再进行渲染。

标记为洋红色:UIView 的 frame 像素不对齐,即不能换算成整数像素值。

解决

Swift

func Get375Width(width:CGFloat) -> CGFloat {
	return ceil(width * Constants.screenWidth/375.0)
}

标记为黄色:UIImageView 的图片像素大小与其 frame.size 不对齐,图片发生了缩放造成。

解决

Swift

let imageWidth = Constants.isIphoneX ? (imageView.bounds.width * 3) : (imageView.bounds.width * 2)

Color Copied Images

当图片的颜色格式 GPU 不支持的时候,Core Animation会拷贝一份数据让CPU进行转化。苹果的GPU只解析32bit的颜色格式。

Color Blended Layer
混合绘制,图片不透明(png),视图容器不透明
UIView/CALayer 的 alpha 小于 1.0;
UIImageView 的 image 含有透明通道

解决
尽量使用不透明图层,图片中去掉不必要的透明。

Color Offscreen-Rendered
离屏渲染

iOS 中主要的渲染操作都是由 CoreAnimation的 Render Server 模块来调用下层接口处理。通常对于每一层layer,Render Server会遵循“画家算法”,按次序输出到frame buffer,后一层覆盖前一层,就能得到最终的显示结果。

然而有些场景并没有那么简单。作为“画家”的GPU虽然可以一层一层往画布上进行输出,但是无法在某一层渲染完成之后,再回过头来擦除/改变其中的某个部分。
要么能找到一种通过单次遍历就能完成渲染的算法,要么就不得不另开一块内存,借助这个临时中转区域来完成一些更复杂的、多次的修改/剪裁操作。

上面开辟空间渲染的过程,就算离屏渲染。

主要会产生离屏渲染的场景有

1cornerRadius+clipsToBounds
2shadow
3UIBlurEffect
4mask

解决

●cornerRadius+clipsToBounds
单独使用cornerRadius。
创建四个弧形Layer,或者图片盖住四个角
●View的圆形边框

如果没有backgroundColor可以使用cornerRadius来做

●shadow

使用shadowPath

●mask

使用layer mask并打开shouldRasterize来对渲染结果进行缓存

●UIBlurEffect

不采用系统提供的UIVisualEffect,而是另外实现模糊效果(CIGaussianBlur),并手动管理渲染结果

大尺寸图片

像我们首页大促这种大尺寸,我们会做切割分成多个图片,将渲染时间切割开分段加载。

青山不改,绿水长流。谢谢大家!

posted @   一眼万年的星空  阅读(173)  评论(0编辑  收藏  举报
编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示