Skip to content

扁平化视图

View Flattening 是 React Native 渲染器的一种优化,用于避免深度布局树。

React API 通过组合被设计成声明性的和可重用的。这为直观开发提供了一个很好的模型。然而,在实现中,API 的这些特性导致了创建的 React Element Trees 有一定的深度,不过其中大部分的 React Element node 只影响视图的布局,而不会在屏幕上呈现任何东西。我们称这些类型的节点为“Layout-Only”节点。

从概念上讲,React Element Tree的每个节点都与屏幕上的视图有1<1的关系>,因此渲染一个由大量“Layout-Only”节点组成的深度React Element Tree会导致渲染时性能较差。

下面是一个受“Layout Only”视图成本影响的常见用例。

假设您想要呈现一个由TitleComponent处理的图像和标题,并且将该组件包含为ContainerComponent的子组件,该组件具有一些边距样式。在分解组件之后,React代码看起来像这样:

function MyComponent() {
return (
<View> // ReactAppComponent
<View style={{margin: 10}} /> // ContainerComponent
<View style={{margin: 10}}> // TitleComponent
<Image {...} />
<Text {...}>This is a title</Text>
</View>
</View>
</View>
);
}

作为渲染过程的一部分,React Native将生成以下树:

image-20220715164544442

注意,视图(2)和(3)是“Layout-Only”视图,因为它们是在屏幕上渲染的,但它们只在子视图的顶部渲染10像素的边距。

为了提高这些类型的React Element tree的性能,渲染器实现了一个视图扁平化机制,该机制合并或扁平化这些类型的节点,减少了呈现在屏幕上的宿主视图层次结构的深度。这个算法考虑了像margin, padding, backgroundColor,opacity等属性。

视图扁平化算法被设计为渲染器 diffing 阶段的一部分,这意味着我们不需要使用额外的CPU周期来优化React Element Tree来扁平化这些类型的视图。作为核心的其他部分,视图扁平化算法是用c++实现的,它的好处默认在所有支持的平台上共享。

在前面的示例中,视图 (2) 和 (3) 将作为“差异算法”的一部分被扁平化,因此它们的样式将合并到视图 (1) 中:

image-20220715164606651

需要注意的是,这种优化允许渲染器避免创建和渲染两个宿主视图。 从用户的角度来看,屏幕上没有可见的变化。