跳到主要内容

视图扁平化

注意

本文档引用了新架构,该架构正在积极推广中。

视图展平是 React Native 渲染器的一项优化,旨在避免过深的布局树。

React API 的设计是声明式的,并且可以通过组合来实现重用。这提供了一个优秀的直观开发模型。然而,在实现过程中,API 的这些特性会导致创建过深的 React Element 树,其中绝大多数 React Element 节点仅影响 View 的布局,而不在屏幕上渲染任何内容。我们将这类节点称为“仅布局”节点。

从概念上讲,React Element 树中的每个节点都与屏幕上的一个视图存在 1:1 的关系。因此,渲染一个由大量“仅布局”节点组成的深度 React Element 树会导致渲染性能不佳。

以下是一个常见的受“仅布局”视图成本影响的用例。

假设您想渲染一个图像和一个由 TitleComponent 处理的标题,并将此组件作为 ContainerComponent 的子组件,该组件具有一些边距样式。分解组件后,React 代码将如下所示:

jsx
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 将生成以下树:

Diagram one

请注意,视图 (2) 和 (3) 是“仅布局”视图,因为它们在屏幕上渲染,但它们只在其子视图之上渲染 10 pxmargin

为了提高这类 React Element 树的性能,渲染器实现了一个视图展平机制,该机制会合并或展平这类节点,从而减少屏幕上渲染的 宿主视图层级的深度。该算法考虑了 marginpaddingbackgroundColoropacity 等属性。

视图展平算法是作为渲染器 diffing 阶段的一部分集成的,这意味着我们不需要额外的 CPU 周期来优化 React Element 树中这类视图的展平。与核心的其他部分一样,视图展平算法是用 C++ 实现的,其优势在所有支持的平台上默认共享。

在前面的示例中,视图 (2) 和 (3) 将在“diffing 算法”过程中被展平,并因此将它们的样式合并到视图 (1) 中。

Diagram two

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