Skip to main content

视图扁平化

提醒

本文档涉及正在积极推出的 新架构

¥This document refers to the New Architecture, that is in active roll-out.

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

¥View Flattening is an optimization by the React Native renderer to avoid deep layout trees.

React API 被设计为声明性的并且可通过组合重用。这为直观开发提供了一个很好的模型。然而,在实现中,API 的这些品质导致了深度 React 元素树 的创建,其中绝大多数 React 元素节点仅影响视图的布局,不会在屏幕上渲染任何内容。我们将这些类型的节点称为“仅布局”节点。

¥The React API is designed to be declarative and reusable through composition. This provides a great model for intuitive development. However, in implementation, these qualities of the API lead to the creation of deep React Element Trees, where a large majority of React Element Nodes only affect the layout of a View and don’t render anything on the screen. We call these types of nodes “Layout-Only” Nodes.

从概念上讲,React Element Tree 的每个节点与屏幕上的视图都是 1:1 的关系,因此渲染由大量“Layout-Only”节点组成的深层 React Element Tree 会导致性能不佳。 渲染。

¥Conceptually, each of the Nodes of the React Element Tree have a 1:1 relationship with a view on the screen, therefore rendering a deep React Element Tree that is composed by a large amount of “Layout-Only” Node leads to poor performance during rendering.

以下是受 "仅布局" 视图成本影响的常见用例。

¥Here is a common use case that is affected by the cost of "Layout Only" views.

想象一下,你想要渲染由 TitleComponent 处理的图片和标题,并且将此组件作为具有一些边距样式的 ContainerComponent 的子组件包含在内。分解组件后,React 代码将如下所示:

¥Imagine you want to render an image and a title that is handled by the TitleComponent, and you include this component as a child of the ContainerComponent that has some margin styles. After decomposing the components, the React code would look like this:

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

¥As part of the render process, React Native will produce the following trees:

Diagram one

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

¥Note that the Views (2) and (3) are “Layout Only” views, because they are rendered on the screen but they only render a margin of 10 px on top of their children.

为了提高这些类型的 React 元素树的性能,渲染器实现了一种视图扁平化机制,该机制可以合并或扁平化这些类型的节点,从而减少在屏幕上渲染的 主机视图 层次结构的深度。该算法考虑了以下属性:marginpaddingbackgroundColoropacity

¥To improve the performance of these types of React Element Trees, the renderer implements a View Flattening mechanism that merges or flattens these types of Nodes, reducing the depth of the host view hierarchy that is rendered on the screen. This algorithm takes into consideration props like: margin, padding, backgroundColor, opacity, etc.

视图扁平化算法在设计上集成为渲染器差异阶段的一部分,这意味着我们不会使用额外的 CPU 周期来优化 React Element Tree 扁平化这些类型的视图。与核心的其余部分一样,视图扁平化算法是用 C++ 实现的,并且默认情况下在所有支持的平台上共享其优点。

¥The View Flattening algorithm is integrated by design as part of the diffing stage of the renderer, which means that we don’t use extra CPU cycles to optimize the React Element Tree flattening these types of views. As the rest of the core, the View flattening algorithm is implemented in C++ and its benefits are shared by default on all supported platforms.

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

¥In the case of the previous example, the Views (2) and (3) would be flattened as part of the “diffing algorithm” and as a result their styles will be merged into the View (1):

Diagram two

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

¥It is important to note that this optimization allows the renderer to avoid the creation and render of two host views. From the user’s perspective there are no visible changes on the screen.