(译)理解ConstraintLayout性能上的好处
本文介绍了ConstraintLayout对于性能方面的好处并和传统布局做了比较。
转载自作者 于卫国
地址 https://www.jianshu.com/p/fae1d533597b
《钱塘湖春行》
孤山寺北贾亭西, 水面初平云脚低。
几处早莺争暖树, 谁家新燕啄春泥。
乱花渐欲迷人眼, 浅草才能没马蹄。
最爱湖东行不足, 绿杨阴里白沙堤。
-唐,白居易
本文首发:http://yuweiguocn.github.io/
关于ConstraintLayout的使用介绍请查看ConstraintLayout的使用。
原文链接:Understanding the performance benefits of ConstraintLayout
自从去年Google I/O大会发布了ConstraintLayout,我们一直在持续提升布局的稳定性及布局编辑器的支持。我们也添加了针对ConstraintLayout的新特性来帮助你构建不同类型的布局。例如约束链和设置大小比例。除了这些特性,使用ConstraintLayout有一个值得注意的性能上的好处。在这篇文章中,我们会看看ConstraintLayout带来哪些性能提升。
Android是怎样绘制View的?
为了更好的理解ConstraintLayout的性能,我们来回顾一下Android是怎样绘制View的。
当用户让一个Android view获得焦点,Android框架会指导View绘制它自己。这个处理过程包括3个阶段:
1.测量(Measure)
系统完成View树从上到下的遍历决定每个ViewGroup有多大和View元素是什么。当一个ViewGroup被测量,它也会测量它的子View。
2.布局(Layout)
另一个从上到下遍历的发生,每个ViewGroup使用在测量阶段决定的大小确定子View的位置。
3.绘制(Draw)
没错,又一个从上到下的遍历。对于View树中的每个对象,创建的Canvas对象用于发送绘制命令列表到GPU。这些命令包括系统在前两个阶段确定的ViewGroup和View对象的大小和位置。
图1 测量阶段遍历一个View树的示例
绘制过程中的每个阶段需要从上到下遍历View树。因此,在View层级中互相嵌入的View越多,设备用于绘制View的所需时间和计算能力越多。通过在应用布局保持扁平层级,你可以创建一个快速响应用户界面的应用。
传统布局层级的消耗
了解了View的绘制过程,我们使用LinearLayout和RelativeLayout创建一个传统布局层级。
图2 布局示例
我们创建一个如上图所示的布局。如果使用传统布局,XML文件包含的元素和下面类似:
<RelativeLayout><ImageView /><ImageView /><RelativeLayout><TextView /><LinearLayout><TextView /><RelativeLayout><EditText /></RelativeLayout></LinearLayout><LinearLayout><TextView /><RelativeLayout><EditText /></RelativeLayout></LinearLayout><TextView /></RelativeLayout><LinearLayout ><Button /><Button /></LinearLayout>
</RelativeLayout>
尽管在这种类型的View层级中有改进的余地,但你仍需要创建一些嵌套View层级。
正如之前说过的,嵌套层级会影响性能。我们使用Android Studio的Systrace工具看看嵌套层级对UI性能有哪些实际影响。我们用编程的方式调用每个ViewGroup(ConstraintLayout 和 RelativeLayout)的测量和布局并且当测量和布局执行的时候触发Systrace。下面的命令会生成一个包含关键事件的概览文件,例如昂贵的测量/布局的传递,时间在20秒以内。
python $ANDROID_HOME/platform-tools/systrace/systrace.py --time=20 -o ~/trace.html gfx view res
关于可以怎样使用Systrace的详情,请查看Analyzing UI Performance with Systrace指南。
Systrace会自动高亮这个布局的性能问题,以及一些修改它们的建议。通过点击"Alerts"标签,你会发现绘制这个View层级在测量和布局阶段需要80多个昂贵的传递!
在测量和布局阶段触发很多昂贵的传递并不是我们想要的,大量的绘制活动会导致掉帧引起用户的注意。我们可以得出结论由于嵌套层级会降低性能,正如RelativeLayout会测量它的子View两次。
图3 从Systrace查看使用RelativeLayout布局的警告
可以从GitHub获取完整源码查看我们是怎样执行测量的。
ConstraintLayout的好处
如果你使用ConstraintLayout创建同样的布局,XML文件包含的元素层级就像下面这样:
<android.support.constraint.ConstraintLayout><ImageView /><ImageView /><TextView /><EditText /><TextView /><TextView /><EditText /><Button /><Button /><TextView />
</android.support.constraint.ConstraintLayout>
如上所示,布局有一个完全扁平的层级。这是由于ConstraintLayout允许你创建复杂的布局不用嵌套View和ViewGroup元素。
例如,我们来看下布局中间的TextView和EditText:
当使用RelativeLayout,你需要创建一个ViewGroup垂直对齐EditText和TextView:
<LinearLayoutandroid:id="@+id/camera_area"android:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"android:layout_below="@id/title" ><TextViewandroid:text="@string/camera"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center_vertical"android:id="@+id/cameraLabel"android:labelFor="@+id/cameraType"android:layout_marginStart="16dp" /><RelativeLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"><EditTextandroid:id="@+id/cameraType"android:ems="10"android:inputType="textPersonName"android:text="@string/camera_value"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_centerVertical="true"android:layout_marginTop="8dp"android:layout_marginStart="8dp"android:layout_marginEnd="8dp" /></RelativeLayout>
</LinearLayout>
通过使用ConstraintLayout,你可以实现同样的效果,只需要从TextView的基线添加一个约束到EditText的基线,不用创建其它ViewGroup:
图4 EditText和TextView之间的约束
<TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"app:layout_constraintLeft_creator="1"app:layout_constraintBaseline_creator="1"app:layout_constraintLeft_toLeftOf="@+id/activity_main_done"app:layout_constraintBaseline_toBaselineOf="@+id/cameraType" />
当对我们使用ConstraintLayout的布局运行Systrace工具,你可以看到在同样20秒内只有很少的昂贵测量/布局传递。这对于提升性能是有意义的,现在我们保持了View层级的扁平化。
图5 从Systrace查看使用ConstraintLayout布局的警告
有一点需要注意,我们可以只使用布局编辑器构建ConstraintLayout布局而不用手动编辑XML文件。对于使用RelativeLayout实现同样的效果,我们可能需要手动编辑XML文件。
测量性能差异
我们分析了两种类型的布局ConstraintLayout和RelativeLayout的测量和布局传递有多长,通过使用 OnFrameMetricsAvailableListener,Android 7.0 (API level 24)引入。这个类可以收集应用的UI渲染帧与帧的时间信息。
通过调用下面的代码,可以开始记录每帧的UI动作:
window.addOnFrameMetricsAvailableListener(frameMetricsAvailableListener, frameMetricsHandler);
时间信息可用之后,应用会触发frameMetricsAvailableListener()回调。我们感兴趣的是测量/布局的性能,因此当我们接收到实际的帧时间调用FrameMetrics.LAYOUT_MEASURE_DURATION。
Window.OnFrameMetricsAvailableListener {_, frameMetrics, _ ->val frameMetricsCopy = FrameMetrics(frameMetrics);// Layout measure duration in nanosecondsval layoutMeasureDurationNs = frameMetricsCopy.getMetric(FrameMetrics.LAYOUT_MEASURE_DURATION);
关于FrameMetrics可以接收的其它类型的信息,请查看FrameMetrics API。
测量结果:ConstraintLayout更快
我们的性能比较显示ConstraintLayout在测量/布局阶段的执行要比RelativeLayout好40%:
图6 测量/布局(单位:毫秒,平均100帧)
上面的结果显示,ConstraintLayout可能比传统布局有更好的性能。此外,ConstraintLayout有其它特性可以帮助你构建复杂和高性能布局,正如ConstraintLayout的好处部分所说。详情请查看ConstraintLayout的使用。我们推荐你使用ConstraintLayout构建你的布局。当之前你需要多层嵌套的布局,ConstraintLayout可以让你的布局有最优的性能和易用性。
附录:测量环境
上面所有的测量在以下环境执行。
Device | Android Version | ConstraintLayout version |
---|---|---|
Nexus 5X | 8.0 | 1.0.2 |
What's next
查看ConstraintLayout的使用,API文档,Medium上的文章完全理解ConstraintLayout可以为你提供什么。再次感谢我们发布ConstraintLayout alpha版本以来提交反馈和问题的所有人。我们真心感激年初发布的ConstraintLayout 1.0版本。我们会继续提升ConstraintLayout,请继续使用Android issue tracker给我们发送反馈。
作者:于卫国
链接:https://www.jianshu.com/p/fae1d533597b
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
(译)理解ConstraintLayout性能上的好处相关推荐
- 理解ConstraintLayout性能上的好处(转载,仅供学习)
本文转载自:https://www.jianshu.com/p/fae1d533597b,仅供学习 (译)理解ConstraintLayout性能上的好处 本文介绍了ConstraintLayout对 ...
- [译] 2019 前端性能优化年度总结 — 第五部分
原文地址:Front-End Performance Checklist 2019 - 5 原文作者:Vitaly Friedman 译文出自:掘金翻译计划 本文永久链接:github.com/xit ...
- mysql优化十:从架构角度全局理解mysql性能优化
从架构角度全局理解mysql性能优化 MySQL性能优化其实是个很大的课题,在优化上存在着一个调优金字塔的说法: 很明显从图上可以看出,越往上走,难度越来越高,收益却是越来越小的.比如硬件和 OS调优 ...
- c语言中内循环和外循环的位置可能产生性能上的区别
∇ \nabla ∇ 联系方式: e-mail: FesianXu@gmail.com QQ: 973926198 github: https://github.com/FesianXu 知乎专栏: ...
- [译] 理解 NPM 5 中的 lock 文件
本文讲的是[译] 理解 NPM 5 中的 lock 文件, 原文地址:Understanding lock files in NPM 5 原文作者:Jiří Pospíšil 译文出自:掘金翻译计划 ...
- 10个问题带你全面理解Linux性能优化
10个问题带你全面理解Linux性能优化 • Feiskyhttps://feisky.xyz/posts/2020-06-06-linux-perf/本文整理自极客时间"10个问题带你全面 ...
- HTTP2.0,HTTP1.1,HTTP1.0三者在通性性能上的优化方法
本文从从通信性能角度,来分析对比HTTP1.0和HTTP1.1之间的区别.以及HTTP1.1与HTTP2.0之间的区别.本文详细内容组织如下 目录 一丶HTTP1.0与HTTP1.1通信性能上的区别 ...
- 深入理解JVM性能调优
深入理解JVM性能调优 您的评价: 收藏该经验 width="728" height="90" frameborder="0&q ...
- [译] 2019 前端性能优化年度总结 — 第三部分
原文地址:Front-End Performance Checklist 2019 - 3 原文作者:Vitaly Friedman 译文出自:掘金翻译计划 本文永久链接:github.com/xit ...
最新文章
- TP5实现邮件发送(PHP 利用QQ邮箱发送邮件「PHPMailer」)
- 函数 —— strtok() 例如:按照字符拆分字符串,放入新定义的数组中;按照字符拆分字符串,放入原先的数组中
- Struts 2再曝远程代码执行漏洞S2-037
- CA双向认证的时候,如果一开始下载的证书就有问题的,怎么保证以后的交易没有问题?...
- 【生活智慧】005.信守诺言的约束
- Jenkins 随笔
- 2、mybatis的基本使用
- SaaS窘境[欣赏然后翻译之]
- Linux内存管理:内存寻址之分段机制与分页机制
- 计算机90学时培训小结,90学时培训学习心得体会
- 小程序常用api总结
- 使用 Kitten 开发一款趣味成语接龙游戏
- Web前端知识点总结(持续更新中...)
- 实习僧——数据分析岗招聘信息爬取 源代码
- SQL SEVER select对象名无效
- 我的世界无限资源的服务器,我的世界无限资源单机版
- SQL Round 取整千 整百 整万
- SWT学习|常用组件及参数
- 关于Android Pie(Android 9.0)
- Vue 删除列表项的淡出动画