公众号「稀有猿诉」 原文链接 降Compose十八掌之『履霜冰至』| Phases
这篇文章译自Jetpack Compose phases
就像大多数其他的UI工具集一样,Compose渲染一帧也要经过几个不同的阶段。就比如说Android view系统,主要有三个阶段:测量(measure),版面编排(layout)和绘制(drawing)。Compose也非常的类似,但有一个特别重要的额外的阶段起始时的组合(composition)阶段。
组合在我们前面的文章中有详细的描述,包括降Compose十八掌之『潜龙勿用』| Thinking in Compose和降Compose十八掌之『鸿渐于陆』| State。
每一帧的三个阶段
Compose有三个主要的阶段:
- 组合(Composition):要显示什么。Compose运行composable函数并创建UI的一个描述。
- 版面编排(Layout):在哪里显示。这个阶段包含两个步骤:测量(measurement)和放置(placement)。给布局树中的每个节点,在二维坐标中,布置元素的测量然后放置它们和它们的子元素。
- 绘制(Drawing):如何渲染。把UI元素绘制进一个Canvas,也就是设备的屏幕上。
> 图1. Compose把数据转化为UI的三个阶段
这三个阶段的执行顺序是相同的,能够让数据从组合到版面编排再到绘制沿着一个方向流动,以生成一帧(也就是「单向数据流」)。需要特别注意的例外是BoxWithConstraints,LazyColumn和LazyRow,它们子节点的组合依赖于父节点的排版阶段。
可以假定每一帧都会这三个阶段,但是基于性能的考量,在所有的阶段里,Compose会避免相同输入时计算结果相同的重复工作。如果一个composable函数能复用前一次的结果,Compose会跳过它的执行,并且如果没有必要,Compose UI并不会重新排版或者重新绘制整个UI树。Compose仅会做更新UI所必要的最少工作。因为Compose会在不同的阶段追踪状态读取,所以这种优化是可行的。
理解不同的阶段
这部分将详细的描述composables的三个渲染阶段是如何进行的。
组合(Composition)
在组合阶段,Compose运行时会执行composable函数然后输出一个能代表UI的树形结构。这个树形结构由包含着下一阶段所需要的信息的布局节点组成,如下面这个视频所示: