Skip to content

Commit

Permalink
Unversion Architecture docs (#3000)
Browse files Browse the repository at this point in the history
Co-authored-by: Bartosz Kaszubowski <gosimek@gmail.com>
  • Loading branch information
slorber and Simek committed Mar 10, 2022
1 parent 44a0689 commit 548330d
Show file tree
Hide file tree
Showing 28 changed files with 108 additions and 1,073 deletions.
28 changes: 0 additions & 28 deletions docs/fabric-renderer.md

This file was deleted.

File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
---
id: architecture-glossary
title: Glossary
slug: /glossary
---

## Fabric Renderer
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
---
id: architecture-overview
title: Architecture Overview
slug: /overview
---

This section is a work in progress intended to share conceptual overviews of how React Native's architecture works. Its intended audience includes library authors, core contributors, and the exceptionally curious. It is not a requirement to be familiar with this material to use React Native.
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,26 @@ id: fabric-renderer
title: Fabric
---

Fabric is React Native's new rendering system, a conceptual evolution of the legacy render system. The core principles are to unify more render logic in C++, improve interoperability with [host platforms](architecture-glossary#host-platform), and to unlock new capabilities for React Native. Development began in 2018 and in 2021, React Native in the Facebook app is backed by the new renderer.
Fabric is React Native's new rendering system, a conceptual evolution of the legacy render system. The core principles are to unify more render logic in C++, improve interoperability with [host platforms](architecture-glossary.md#host-platform), and to unlock new capabilities for React Native. Development began in 2018 and in 2021, React Native in the Facebook app is backed by the new renderer.

This documentation provides an overview of the [new renderer](architecture-glossary#fabric-render) and its concepts. It avoids platform specifics and doesn’t contain any code snippets or pointers. This documentation covers key concepts, motivation, benefits, and an overview of the render pipeline in different scenarios.
This documentation provides an overview of the [new renderer](architecture-glossary.md#fabric-render) and its concepts. It avoids platform specifics and doesn’t contain any code snippets or pointers. This documentation covers key concepts, motivation, benefits, and an overview of the render pipeline in different scenarios.

## Motivations and Benefits of the new renderer

The render architecture was created to unlock better user experiences that weren’t possible with the legacy architecture. Some examples include:

- With improved interoperability between [host views](architecture-glossary#host-view-tree-and-host-view) and React views, the renderer is able to measure and render React surfaces synchronously. In the legacy architecture, React Native layout was asynchronous which led to a layout “jump” issue when embedding a React Native rendered view in a _host view_.
- With improved interoperability between [host views](architecture-glossary.md#host-view-tree-and-host-view) and React views, the renderer is able to measure and render React surfaces synchronously. In the legacy architecture, React Native layout was asynchronous which led to a layout “jump” issue when embedding a React Native rendered view in a _host view_.
- With support of multi-priority and synchronous events, the renderer can prioritize certain user interactions to ensure they are handled in a timely manner.
- [Integration with React Suspense](https://reactjs.org/blog/2019/11/06/building-great-user-experiences-with-concurrent-mode-and-suspense.html) which allows for more intuitive design of data fetching in React apps.
- Enable React [Concurrent Features](https://github.com/reactwg/react-18/discussions/4) on React Native.
- Easier to implement server side rendering for React Native.

The new architecture also provides benefits in code quality, performance, and extensibility:

- **Type safety:** code generation to ensure type safety across the JS and [host platforms](architecture-glossary#host-platform). The code generation uses JavaScript component declarations as source of truth to generate C++ structs to hold the props. Mis-match between JavaScript and host component props triggers a build error.
- **Type safety:** code generation to ensure type safety across the JS and [host platforms](architecture-glossary.md#host-platform). The code generation uses JavaScript component declarations as source of truth to generate C++ structs to hold the props. Mismatch between JavaScript and host component props triggers a build error.
- **Shared C++ core**: the renderer is implemented in C++ and the core is shared among platforms. This increases consistency and makes it easier to adopt React Native on new platforms.
- **Better Host Platform Interoperability**: Synchronous and thread-safe layout calculation improves user experiences when embedding host components into React Native, which means easier integration with host platform frameworks that require synchronous APIs.
- **Improved Performance**: With the new cross-platform implementation of the renderer system, every platform benefits from performance improvements that may have been motivated by limitations of one platform. For example, view flattening was originally a performance solution for Android and is now provided by default on both Android and iOS.
- **Consistency**: The new render system is cross-platform, it is easier to keep consistency among different platforms.
- **Faster Startup**: Host components are lazily initialized by default.
- **Less serialization of data between JS and host platform**: React used to transfer data between JavaScript and _host platform_ as serialized JSON. The new renderer improves the transfer of data by accessing JavaScript values directly using [JavaScript Interfaces (JSI)](architecture-glossary#javascript-interfaces-jsi).
- **Less serialization of data between JS and host platform**: React used to transfer data between JavaScript and _host platform_ as serialized JSON. The new renderer improves the transfer of data by accessing JavaScript values directly using [JavaScript Interfaces (JSI)](architecture-glossary.md#javascript-interfaces-jsi).
22 changes: 11 additions & 11 deletions docs/render-pipeline.md → website/architecture/render-pipeline.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ import FabricWarning from './\_fabric-warning.mdx';

<FabricWarning />

The React Native renderer goes through a sequence of work to render React logic to a [host platform](architecture-glossary#host-platform). This sequence of work is called the render pipeline and occurs for initial renders and updates to the UI state. This document goes over the render pipeline and how it differs in those scenarios.
The React Native renderer goes through a sequence of work to render React logic to a [host platform](architecture-glossary.md#host-platform). This sequence of work is called the render pipeline and occurs for initial renders and updates to the UI state. This document goes over the render pipeline and how it differs in those scenarios.

The render pipeline can be broken into three general phases:

1. **Render:** React executes product logic which creates a [React Element Tree](architecture-glossary#react-element-tree-and-react-element) in JavaScript. From this tree, the renderer creates a [React Shadow Tree](architecture-glossary#react-shadow-tree-and-react-shadow-node) in C++.
1. **Render:** React executes product logic which creates a [React Element Trees](architecture-glossary.md#react-element-tree-and-react-element) in JavaScript. From this tree, the renderer creates a [React Shadow Tree](architecture-glossary.md#react-shadow-tree-and-react-shadow-node) in C++.
2. **Commit**: After a React Shadow Tree is fully created, the renderer triggers a commit. This **promotes** both the React Element Tree and the newly created React Shadow Tree as the “next tree” to be mounted. This also schedules calculation of its layout information.
3. **Mount:** The React Shadow Tree, now with the results of layout calculation, is transformed into a [Host View Tree](architecture-glossary#host-view-tree-and-host-view).
3. **Mount:** The React Shadow Tree, now with the results of layout calculation, is transformed into a [Host View Tree](architecture-glossary.md#host-view-tree-and-host-view).

> The phases of the render pipeline may occur on different threads. Refer to the [Threading Model](threading-model) doc for more detail.
Expand All @@ -37,13 +37,13 @@ function MyComponent() {
// <MyComponent />
```

In the example above, `<MyComponent />` is a [React Element](architecture-glossary#react-element-tree-and-react-element). React recursively reduces this _React Element_ to a terminal [React Host Component](architecture-glossary#react-host-components-or-host-components) by invoking it (or its `render` method if implemented with a JavaScript class) until every _React Element_ cannot be reduced any further. Now you have a _React Element Tree_ of [React Host Components](architecture-glossary#react-host-components-or-host-components).
In the example above, `<MyComponent />` is a [React Element](architecture-glossary.md#react-element-tree-and-react-element). React recursively reduces this _React Element_ to a terminal [React Host Component](architecture-glossary.md#react-host-components-or-host-components) by invoking it (or its `render` method if implemented with a JavaScript class) until every _React Element_ cannot be reduced any further. Now you have a _React Element Tree_ of [React Host Components](architecture-glossary.md#react-host-components-or-host-components).

### Phase 1. Render

![Phase one: render](/docs/assets/Architecture/renderer-pipeline/phase-one-render.png)

During this process of element reduction, as each _React Element_ is invoked, the renderer also synchronously creates a [React Shadow Node](architecture-glossary#react-shadow-tree-and-react-shadow-node). This happens only for _React Host Components_, not for [React Composite Components](architecture-glossary#react-composite-components). In the example above, the `<View>` leads to the creation of a `ViewShadowNode` object, and the
During this process of element reduction, as each _React Element_ is invoked, the renderer also synchronously creates a [React Shadow Node](architecture-glossary.md#react-shadow-tree-and-react-shadow-node). This happens only for _React Host Components_, not for [React Composite Components](architecture-glossary.md#react-composite-components). In the example above, the `<View>` leads to the creation of a `ViewShadowNode` object, and the
`<Text>` leads to the creation of a `TextShadowNode` object. Notably, there is never a _React Shadow Node_ that directly represents `<MyComponent>`.

Whenever React creates a parent-child relationship between two _React Element Nodes_, the renderer creates the same relationship between the corresponding _React Shadow Nodes_. This is how the _React Shadow Tree_ is assembled.
Expand Down Expand Up @@ -89,7 +89,7 @@ The mount phase transforms the _React Shadow Tree_ (which now contains data from
</View>
```

At a high level, React Native renderer creates a corresponding [Host View](architecture-glossary#host-view-tree-and-host-view) for each _React Shadow Node_ and mounts it on screen. In the example above, the renderer creates an instance of `android.view.ViewGroup` for the `<View>` and `android.widget.TextView` for `<Text>` and populates it with “Hello World”. Similarly for iOS a `UIView` is created with and text is populated with a call to `NSLayoutManager`. Each host view is then configured to use props from its React Shadow Node, and its size and position is configured using the calculated layout information.
At a high level, React Native renderer creates a corresponding [Host View](architecture-glossary.md#host-view-tree-and-host-view) for each _React Shadow Node_ and mounts it on screen. In the example above, the renderer creates an instance of `android.view.ViewGroup` for the `<View>` and `android.widget.TextView` for `<Text>` and populates it with “Hello World”. Similarly for iOS a `UIView` is created with and text is populated with a call to `NSLayoutManager`. Each host view is then configured to use props from its React Shadow Node, and its size and position is configured using the calculated layout information.

![Step two](/docs/assets/Architecture/renderer-pipeline/render-pipeline-3.png)

Expand Down Expand Up @@ -150,7 +150,7 @@ When a state update occurs, the renderer needs to conceptually update the _React

Let’s explore each phase of the render pipeline during a state update.

### Phase 1: Render
### Phase 1. Render

![Phase one: render](/docs/assets/Architecture/renderer-pipeline/phase-one-render.png)

Expand All @@ -173,7 +173,7 @@ After these operations, **Node 1'** represents the root of the new _React Elemen

Notice how **T** and **T'** both share **Node 4**. Structural sharing improves performance and reduces memory usage.

### Phase 2: Commit
### Phase 2. Commit

![Phase two: commit](/docs/assets/Architecture/renderer-pipeline/phase-two-commit.png)

Expand All @@ -185,7 +185,7 @@ After React creates the new _React Element Tree_ and _React Shadow Tree_, it mus
- **Tree Diffing:** This step computes the diff between the “previously rendered tree” (**T**) and the “next tree” (**T'**). The result is a list of atomic mutation operations to be performed on _host views_.
- In the above example, the operations consist of: `UpdateView(**Node 3'**, {backgroundColor: '“yellow“})`

### Phase 3: Mount
### Phase 3. Mount

![Phase three: mount](/docs/assets/Architecture/renderer-pipeline/phase-three-mount.png)

Expand All @@ -211,13 +211,13 @@ With two important differences:
1. They skip the “render phase” since React is not involved.
2. The updates can originate and happen on any thread, including the main thread.

### Phase 2: Commit
### Phase 2. Commit

![Phase two: commit](/docs/assets/Architecture/renderer-pipeline/phase-two-commit.png)

When performing a _C++ State_ update, a block of code requests an update of a `ShadowNode` (**N**) to set _C++ State_ to value **S**. React Native renderer will repeatedly attempt to get the latest committed version of **N**, clone it with a new state **S**, and commit **N’** to the tree. If React, or another _C++ State_ update, has performed another commit during this time, the _C++ State_ commit will fail and the renderer will retry the _C++ State_ update many times until a commit succeeds. This prevents source-of-truth collisions and races.

### Phase 3: Mount
### Phase 3. Mount

![Phase three: mount](/docs/assets/Architecture/renderer-pipeline/phase-three-mount.png)

Expand Down
File renamed without changes.
Loading

0 comments on commit 548330d

Please sign in to comment.