渲染优化

2018-07-09  本文已影响13人  最美下雨天

文章来源:
http://wuxiaolong.me/2017/03/26/Rendering/
https://www.jianshu.com/p/989ce9eb7af8
hz:每秒刷新的次数

著名的“16ms”原则:
我们通常都会提到60fps(Frame Per Second)与16ms,可是知道为何会是以程序是否达到60fps来作为App性能的衡量标准吗?
60fps:人眼与大脑之间的协作无法感知超过60fps的画面更新。
*16ms:因为Android设定的刷新率是60fps,也就是每秒60帧,即16ms=1000/60Hz
Android系统每隔16ms会发出VSYNC信号重绘我们的界面。

就像这样:


image.png

如果你的某个操作花费时间是24ms,系统在得到VSYNC信号的时候就无法进行正常渲染,这样就发生了丢帧现象。那么用户在32ms内看到的会是同一帧画面。


image.png
Overdraw(过度绘制)是指系统在单个渲染帧中多次绘制屏幕上的像素。例如,如果我们有一堆堆叠的UI卡,不可见的UI也在做绘制的操作,这样会浪费大量的CPU和GPU资源。
渲染操作通常依赖于两个核心组件:CPU与GPU。CPU负责包括Measure,Layout,Record,Execute的计算操作,GPU负责Rasterization(栅格化)操作

如何检测?

Overdraw有时候是因为你的UI布局存在大量重叠的部分,还有的时候是因为非必须的重叠背景。例如某个Activity有一个背景,然后里面的Layout又有自己的背景,同时子View又分别有自己的背景。仅仅是通过移除非必须的背景图片,这就能够减少大量的红色Overdraw区域,增加蓝色区域的占比。这一措施能够显著提升程序性能。

image.png

界面上会滚动显示垂直的柱状图来表示每帧画面所需要渲染的时间,柱状图越高表示花费的渲染时间越长。中间有一根绿色的横线,代表16ms,我们需要确保每一帧花费的总时间都低于这条横线,这样才能够避免出现卡顿的问题。

image.png

其实中带有红色或黄色的点代表速度较慢的View。

优化方案:

<merge xmlns:android="http://schemas.android.com/apk/res/android">
 
    <Button
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content"
        android:text="@string/add"/>
 
    <Button
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content"
        android:text="@string/delete"/>
 
</merge>

现在,当你添加该布局文件时(使用<include />标签),系统忽略<merge />节点并且直接添加两个Button。


<ViewStub
    android:id="@+id/stub_import"
    android:inflatedId="@+id/panel_import"
    android:layout="@layout/progress_overlay"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="bottom" />

当你想加载布局时,可以使用下面其中一种方法:


((ViewStub) findViewById(R.id.stub_import)).setVisibility(View.VISIBLE);
// or
View importPanel = ((ViewStub) findViewById(R.id.stub_import)).inflate();

当调用inflate()函数的时候,ViewStub被引用的资源替代,并且返回引用的view。 这样程序可以直接得到引用的view而不用再次调用函数findViewById()来查找了。
注:ViewStub目前有个缺陷就是还不支持 <merge /> 标签。

上一篇 下一篇

猜你喜欢

热点阅读