View Flattening 是 React Native 渲染器的一种优化,用于避免深度布局树。
React API 通过组合被设计成声明性的和可重用的。这为直观开发提供了一个很好的模型。然而,在实现中,API 的这些特性导致了创建的 React Element Trees 有一定的深度,不过其中大部分的 React Element node 只影响视图的布局,而不会在屏幕上呈现任何东西。我们称这些类型的节点为“Layout-Only”节点。
从概念上讲,React Element Tree的每个节点都与屏幕上的视图有1<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将生成以下树:

注意,视图(2)和(3)是“Layout-Only”视图,因为它们是在屏幕上渲染的,但它们只在子视图的顶部渲染10像素的边距。
为了提高这些类型的React Element tree的性能,渲染器实现了一个视图扁平化机制,该机制合并或扁平化这些类型的节点,减少了呈现在屏幕上的宿主视图层次结构的深度。这个算法考虑了像margin, padding, backgroundColor,opacity等属性。
视图扁平化算法被设计为渲染器 diffing 阶段的一部分,这意味着我们不需要使用额外的CPU周期来优化React Element Tree来扁平化这些类型的视图。作为核心的其他部分,视图扁平化算法是用c++实现的,它的好处默认在所有支持的平台上共享。
在前面的示例中,视图 (2) 和 (3) 将作为“差异算法”的一部分被扁平化,因此它们的样式将合并到视图 (1) 中:

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