Skip to content

Commit f3678f5

Browse files
Bartlomiej Bloniarzmeta-codesync[bot]
authored andcommitted
Animation Backend docs (#55488)
Summary: Pull Request resolved: #55488 This diff introduces docs for the Animation Backend # Changelog [General][Added] - AnimationBackend docs Reviewed By: NickGerleman Differential Revision: D92826716 fbshipit-source-id: f3f48f66d85c6a586a520f8015a0f988decc5885
1 parent 4d152ff commit f3678f5

3 files changed

Lines changed: 93 additions & 0 deletions

File tree

__docs__/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ TODO: Explain the different components of React Native at a high level.
4949
- [passChildrenWhenCloningPersistedNodes](../packages/react-native/ReactCommon/react/renderer/core/__docs__/passChildrenWhenCloning.md)
5050
- Layout
5151
- Mounting
52+
- [Animation Backend](../packages/react-native/ReactCommon/react/renderer/animationbackend/__docs__/AnimationBackend.md)
5253
- Native Modules / TurboModules
5354
- JS Runtime
5455
- [Event Loop](../packages/react-native/ReactCommon/react/renderer/runtimescheduler/__docs__/README.md)
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
# Shared Animation Backend
2+
3+
[🏠 Home](../../../../../../../__docs__/README.md)
4+
5+
Shared Animation Backend is a part of the React Native renderer that enables
6+
animation frameworks to update props of React components without going through
7+
React's JavaScript rendering pipeline.
8+
9+
Animation Backend allows for updates of both layout and non-layout props. If
10+
there are no layout updates, the animations will go through the
11+
`synchronouslyUpdateProps` path, otherwise a Fabric commit will be performed. To
12+
synchronize the changes with React, we use the `AnimationBackendCommitHook`.
13+
14+
## 🚀 Usage
15+
16+
The backend is not meant to be used directly. Its main purpose is to serve as a
17+
layer over the Fabric renderer that animation frameworks (like Animated or
18+
Reanimated) can use. A framework that wants to make use of the backend has to
19+
register a callback with the `start` method. The callback will be executed on
20+
each animation frame (supported by native mechanisms like
21+
DisplayLink/Choreographer) and should return a list of prop updates that should
22+
be applied for the given timestamp. To stop receiving callbacks the framework
23+
should call `stop` with the appropriate callbackID. For updates that need to be
24+
applied synchronously (e.g. gesture events), one can use the `trigger` method.
25+
26+
## 📐 Design
27+
28+
![Animation Backend](./AnimationBackend.svg)
29+
30+
The main purpose of the Animation Backend is to bring long-term stability to
31+
animation solutions. The New Architecture was designed to maintain React props
32+
in check with the `ShadowTree`. This poses a problem for any scenario when we
33+
want to apply updates to the `ShadowTree` without going through the React
34+
rendering pipeline, which is exactly what animations want to do. Any commit that
35+
happens outside of React on a different thread will be overwritten by following
36+
React updates, as the new `ShadowTree` revision created by React is based on the
37+
revision that is currently held by React. To mitigate that issue, we use the
38+
`AnimationBackendCommitHook` that runs on every React commit and fixes
39+
overridden props. In this section, we give a more detailed description of the
40+
components that make up the Shared Animation Backend.
41+
42+
### AnimationBackend
43+
44+
This is the heart of the backend. This component is responsible for managing
45+
user-provided callbacks, segregating props, and applying them either through the
46+
`synchronouslyUpdateProps` path (when there are no layout updates), or through a
47+
Fabric commit performed on the main thread. This component is exposed through
48+
`UIManager` with the `UIManagerAnimationBackend` interface.
49+
50+
### AnimatedProps
51+
52+
This is the structure that should be returned by the callback registered with
53+
the `start` method. It represents updates that are to be applied for a single
54+
component identified by `ShadowNodeFamily` in `AnimationMutation`. You shouldn't
55+
interact with this class directly, it's better to use it through the
56+
`PropsBuilder`. `AnimatedProps` support the `RawProps` format, but they also can
57+
hold a vector of `AnimatedProp` (a new C++ structure) for a select subset of the
58+
usual `ViewProps`. These can be applied to the cloned props in a more efficient
59+
way.
60+
61+
### AnimationBackendCommitHook
62+
63+
This component is responsible for keeping animation updates synchronized with
64+
React updates. In Fabric, when React performs a commit, it disregards the
65+
currently mounted revision of the `ShadowTree`. Instead, it bases the new
66+
revision on the `ShadowNodes` it holds. These nodes do not represent any prop
67+
updates that happened when the Animation Backend made a commit on the main
68+
thread (or applied non-layout props through the fast-path). This would create an
69+
issue where a rerender that happens during the animation would display a wrong
70+
state for a split second. To fix this, we also write animation updates to
71+
`AnimatedPropsRegistry`. When React performs a commit, the
72+
`AnimationBackendCommitHook` is able to overwrite any stale props by using the
73+
value from the registry. Since the commit hook runs on React commits, it is safe
74+
for it to use RSNRU to propagate these updates to React. After the commit hook
75+
runs, we clear the registry. If the prop is not explicitly changed by the user
76+
in a render, it will remain unchanged by React on subsequent rerenders.
77+
78+
Additionally, in the callback registered in `start`, one can return a list of
79+
surfaces that should perform a commit on the JS thread, to have the RSNRU
80+
propagate the updates to React. This was used by Animated before the backend was
81+
created.
82+
83+
### AnimationChoreographer
84+
85+
This is an abstraction layer that wraps the native frame callback mechanisms. On
86+
iOS, it has a corresponding `RCTDisplayLink`, and on Android, it uses the
87+
`Choreographer`. For any new platform that wants to adopt the Animation Backend,
88+
this is the part that needs to be implemented.

0 commit comments

Comments
 (0)