当前位置: 首页 > news >正文

Android布局层级过深为什么会对性能有影响?为什么Compose没有布局嵌套问题?

做过布局性能优化的同学都知道,为了优化界面加载速度,要尽可能的减少布局的层级。这主要是因为布局层级的增加,可能会导致测量时间呈指数级增长。

而Compose却没有这个问题,它从根本上解决了布局层级对布局性能的影响: Compose界面只允许一次测量。这意味着随着布局层级的加深,测量时间也只是线性增长的.

下面我们就一起来看看Compose到底是怎么只测量一次就把活给干了的,本文主要包括以下内容:

  • 布局层级过深为什么影响性能?
  • Compose为什么没有布局嵌套问题?

①布局层级过深为什么影响性能?

我们总说布局层级过深会影响性能,那么到底是怎么影响的呢?主要是因为在某些情况下ViewGroup会对子View进行多次测量

举个例子

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="wrap_content"android:layout_height="match_parent"android:orientation="vertical"><Viewandroid:layout_width="match_parent"android:layout_height="100dp"android:background="@android:color/holo_red_dark" /><Viewandroid:layout_width="100dp"android:layout_height="100dp"android:background="@android:color/black" />
</LinearLayout>
  • LinearLayout宽度为wrap_content,因此它将选择子View的最大宽度为其最后的宽度
  • 但是有个子View的宽度为match_parent,意思它将以LinearLayout的宽度为宽度,这就陷入死循环了
  • 因此这时候, LinearLayout 就会先以0为强制宽度测量一下子View,并正常地测量剩下的其他子View,然后再用其他子View里最宽的那个的宽度,二次测量这个match_parent的子 View,最终得出它的尺寸,并把这个宽度作为自己最终的宽度。
  • 这是对单个子View的二次测量,如果有多个子View写了match_parent ,那就需要对它们每一个都进行二次测量。
  • 除此之外,如果在LinearLayout中使用了weight会导致测量3次甚至更多,重复测量在Android中是很常见的

上面介绍了为什么会出现重复测量,那么会有什么影响呢?不过是多测量了几次,会对性能有什么大的影响吗?

之所以需要避免布局层级过深是因为它对性能的影响是指数级的

  • 如果我们的布局有两层,其中父View会对每个子View做二次测量,那它的每个子View一共需要被测量 2 次

  • 如果增加到三层,并且每个父View依然都做二次测量,这时候最下面的子View被测量的次数就直接翻倍了,变成 4 次

  • 同理,增加到 4 层的话会再次翻倍,子 View 需要被测量 8 次

也就是说,对于会做二次测量的系统,层级加深对测量时间的影响是指数级的,这就是Android官方文档建议我们减少布局层级的原因

②Compose为什么没有布局嵌套问题?

我们知道,Compose只允许测量一次,不允许重复测量。

如果每个父组件对每个子组件只测量一次,那就直接意味着界面中的每个组件只会被测量一次

这样即使布局层级加深,测量时间却没有增加,把组件加载的时间复杂度从O(2ⁿ) 降到了 O(n)。

那么问题就来了,上面我们已经知道,多次测量有时是必要的,但是为什么Compose不需要呢?

Compose中引入了固有特性测量(Intrinsic Measurement)

固有特性测量即Compose允许父组件在对子组件进行测量之前,先测量一下子组件的「固有尺寸」

我们上面说的,ViewGroup的二次测量,也是先进行这种「粗略测量」再进行最终的「正式测量」,使用固有特性测量可以产生同样的效果

而使用固有特性测量之所以有性能优势,主要是因为其不会随着层级的加深而加倍,固有特性测量也只进行一次

Compose会先对整个组件树进行一次Intrinsic测量,然后再对整体进行正式的测量。这样开辟两个平行的测量过程,就可以避免因为层级增加而对同一个子组件反复测量所导致的测量时间的不断加倍了。

总结成一句话就是,在Compose里疯狂嵌套地写界面,和把所有组件全都写进同一层里面,性能是一样的!所以Compose没有布局嵌套问题

Android 学习笔录

Kotlin 篇:https://qr18.cn/CdjtAF
Android 性能优化篇:https://qr18.cn/FVlo89
Android 车载篇:https://qr18.cn/F05ZCM
Android Framework底层原理篇:https://qr18.cn/AQpN4J
Android 音视频篇:https://qr18.cn/Ei3VPD
Jetpack全家桶篇(内含Compose):https://qr18.cn/A0gajp
Gradle 篇:https://qr18.cn/DzrmMB
OkHttp 源码解析笔记:https://qr18.cn/Cw0pBD
Flutter 篇:https://qr18.cn/DIvKma
Android 八大知识体:https://qr18.cn/CyxarU
Android 核心笔记:https://qr21.cn/CaZQLo
Android 面试题锦:https://qr18.cn/CKV8OZ

http://www.lryc.cn/news/43799.html

相关文章:

  • 【UR机械臂CB3 网络课程 】
  • dp-统计字典序元音字符串的数目
  • LFM雷达实现及USRP验证【章节3:连续雷达测距测速】
  • COLMAP多视角视图数据可视化
  • 2023年全国最新高校辅导员精选真题及答案36
  • ThreeJS-全屏和退出全屏、自适应大小(五)
  • 等级保护2.0要求及所需设备清单
  • 【大数据之Hadoop】六、HDFS之NameNode、Secondary NameNode和DataNode的内部工作原理
  • 小黑子—Java从入门到入土过程:第四章
  • 数据库原理及应用(四)——SQL语句(2)SQL基础查询以及常见运算符
  • (算法基础)Floyd算法
  • SQL语法:浅析select之七大子句
  • 中国人民大学与加拿大女王大学金融硕士——去有光的地方,并成为自己的光
  • Python数据结构与算法篇(五)-- 二分查找与二分答案
  • 小游戏也要讲信用
  • 贪心算法11
  • 【并发编程】JUC并发编程(彻底搞懂JUC)
  • Compose 动画 (七) : 高可定制性的动画 Animatable
  • vue3组件传值
  • 小白开发微信小程序00--文章目录
  • 随手记录第九话 -- Java框架整合篇
  • 电影《铃芽之旅》观后感
  • Web自动化测试(二)(全网最给力自动化教程)
  • 【C语言经典例题!】逆序字符串
  • 21 - 二叉树(三)
  • 【A-Star算法】【学习笔记】【附GitHub一个示例代码】
  • 纽扣电池澳大利亚认证的更新要求
  • 零代码零距离,明道云开放日北京站圆满结束
  • 第五章Vue路由
  • Git常用指令