性能优化02-布局优化

作者: 最爱的火 | 来源:发表于2018-05-14 09:13 被阅读47次

性能优化02-布局优化

一、CPU与GPU

1、定义

为什么要了解CPU与GPU呢?因为布局绘制就是CPU与GPU实现的。

CPU:负责把布局文件加载到内存中,然后计算所有控件的位置和大小等,得到向量图形。

GPU:负责对CPU传来的向量图形层层渲染,即栅格化填充。

显示器:负责将GPU渲染的图形显示出来。

2、GPU缓冲机制

GPU缓冲机制是指缓存CPU传来的向量图形。

CPU计算布局文件的过程是很耗时的,而实际项目中经常会用到相同的布局文件,这个时候缓冲就有必要了。

3、绘制时间

绘制时间是指CPU开始加载布局文件到GPU完成渲染的时间。

绘制时间由xml文件的复杂程度决定。

4、卡顿分析

我们知道,手机显示器每隔16ms刷新一次屏幕。

那为什么是16ms呢?因为16ms一个画面即60fps,低于60fps,用户就会感觉卡顿。

如果屏幕刷新的时候,绘制没有完成,那么就要等16ms后才能显示,而不是绘制完成就显示。这个时候,就会出现丢帧,用户会感觉卡顿。

二、布局优化

布局是指xml文件和自定义控件。

布局文件越复杂,绘制时间就越长,就越容易卡顿。

那么怎么优化布局呢?

  1. 减少布局层数
  2. 减少过度绘制
  3. 减少控件数量

1、减少布局层数

要减少布局层数,先要查看布局层数。这里使用Hierarchy Viewer工具。

怎么减少布局层数呢?

常用的办法:Relativelayout布局、merge标签、viewStub标签、include标签

Hierarchy Viewer

使用:通过ddms工具打开。

说明:每个view包含Measure, Layout和Draw

颜色:

  1. 绿: 表示该View的此项性能比该View Tree中超过50%的View都要快;例如,代表Measure的是绿点,意味着这个视图的测量时间快于树中的视图对象的50%。
  2. 黄: 表示该View的此项性能比该View Tree中超过50%的View都要慢;
  3. 红: 表示该View的此项性能是View Tree中最慢的;。

绘制时间:点击三色圆圈,即可显示加载时间。布局越复杂,等待显示时间越长。

Relativelayout布局

Relativelayout布局相比Linearlayout布局,更加灵活,但是性能要低。

如果使用Linearlayout布局时,布局层数太多,就需要使用Relativelayout布局。

merge标签

merge标签在布局文件中会包含子控件,但是实际绘制时会被忽略,从而减少布局层数。

注意:自定义控件不能替换为merge。

viewStub标签

只有设置viewstub为visible、invisible或者调用其inflate()方法时,才会进行绘制。

用法:

    <ViewStub
        android:id="@+id/vs"
        android:layout="@layout/viewstub"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

局限性:

  1. viewstub的引用对象必须是一个layout文件,不能是单个View;
  2. ViewStub在加载完引用的layout后会被移除,所以只能加载一次。

include标签

include标签实际上不能减少布局层数,但是还是能提升性能。

使用include的布局一般会重复使用,由于GPU缓冲机制,所以不会重复CPU计算的过程,从而提升性能。

2、减少过度绘制

过度绘制是指布局渲染的层数过多。需要说明的是,布局的层数多并不一定渲染层数就多。因为容器的背景如果为空,就不会进行渲染。

那怎么检查是否出现过度绘制呢?使用手机端的GUP过度绘制工具。

出现过度绘制后,如何减少过度绘制呢?

  1. xml文件减少重复背景
  2. 自定义控件减少重叠绘制

GUP过度绘制工具

使用:开发者选项-调试调试过度绘制,打开即可。

颜色:

  1. 白色:没有过度绘制
  2. 浅蓝:1层过度绘制
  3. 绿色:2层过度绘制
  4. 浅红:3层过度绘制
  5. 红色:4层过度绘制

xml文件减少重复背景

  1. theme背景与activity背景

    theme都有一个默认背景,每个activity也会设置一张背景。因为activity背景会覆盖theme背景,但是GPU渲染的时候,还是会渲染theme背景,所以要把theme背景设为空。

  2. 容器背景

    如果容器背景与父容器背景相同,就要把容器背景设为空,避免重复渲染。

自定义控件减少重叠绘制

一张画布上包含多个bitmap,并且这些bitmap出现重叠时,就会出现重叠绘制。因为GPU渲染时,会把每个bitmap完全渲染出来,虽然有些被覆盖了。

怎么减少重叠绘制呢?

通过Canvas.clipRect()对画布进行裁剪,裁剪出bitmap要显示的大小,这样GPU渲染时就只渲染要显示的部分。裁剪完,需要调用Canvas.restore()还原画布,让下一个bitmap使用。

3、减少控件数量

这个要从逻辑上调整,这里就不分析了。

相关文章

网友评论

    本文标题:性能优化02-布局优化

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