1.为什么渲染性能很重要
为了达到一些绚丽的效果或动画,我们通常会牺牲一些性能,这样往往会引起页面的卡顿。其实这种用户体验对于用户来说往往是致命的。
2.为什么会卡顿
首先有个概念叫做刷新速率,就是指每秒刷新屏幕的次数,单位是赫兹,是一个取决于硬件的固定参数。市面上大部分的手机是60hz。 1000ms/60hz=16.666ms/frame,也就意味着应用必须在16ms内完成屏幕刷新的全部逻辑操作,如果超过了这个时间,就会出现丢帧状况,这样用户就会感觉到卡顿。例如列表滑动卡顿。


3.出现卡顿的常见原因
渲染主要依赖于两个组件:CPU和GPU。CPU主要负责measure(测量控件大小)、layout(布局控件)、record(创建DisplayList)、execute(执行DisplayList,也就是将绘制指令传递给GPU).GPU主要负责栅格化。如下图:

CPU方面,最常见的性能问题是不必要的布局和失效(invalidation)(检测、解决方法请看这篇文章)。
GPU方面,最常见的性能问题是过渡绘制。(检测、解决方法请看这篇文章)

4.activity是如何绘制到屏幕上的
activity的画面是如何绘制到屏幕上的?那些复杂的XML布局文件又是如何能够被识别并绘制出来的?
CPU负责把UI组件计算成Polygons,Texture纹理,然后交给GPU进行栅格化渲染。

然而每次从CPU转移到GPU是一件很麻烦的事情,所幸的是OpenGL ES可以把那些需要内容保存在GPU Memory里面,在下次需要渲染的时候直接进行操作。
5.CPU部分
为了在屏幕上绘制某个东西,Android通常将高级XML文件转换为GPU能够识别的对象 ,然后显示在屏幕上。这个操作是在DisplayList的帮助下完成的。DisplayList包括GPU渲染view所需的所有信息。它包括GPU要绘制的全部对象的信息列表,还有执行绘制操作的OpenGL命令列表。
在某个view第一次需要被渲染时,DisplayList会因此被创建 ,当这个view要显示在屏幕上时,CPU会将绘制指令提交给GPU来执行DisplayList。如下图:

如果你在后续有执行类似移动这个View的位置等操作而需要再次渲染这个View时,我们就仅仅需要额外操作一次渲染指令就够了。如下图:

然而如果你修改了View中的某些可见部分内容,那么之前的DisplayList就无法继续使用了,我们需要重新创建一个DisplayList并重新执行渲染指令更新到屏幕上。

任何时候View中的绘制内容发生变化时,都会重新执行创建DisplayList,渲染DisplayList,更新到屏幕上等一系列操作。这个流程的表现性能取决于你的View的复杂程度,View的状态变化以及渲染管道的执行性能。举个例子,假设某个Button的大小需要增大到目前的两倍,在增大Button大小之前,需要通过父View重新计算并摆放其他子View的位置。修改View的大小会触发整个HierarcyView的重新计算大小的操作。如果是修改View的位置则会触发HierarchView重新计算其他View的位置。如果布局很复杂,这就会很容易导致严重的性能问题。如下图:


网友评论