Summary:
We introduce a few optimizations:
(1) Previous diff: We defer calling any NativeAnimatedModule methods by waiting 1ms before flushing the queue, and debouncing until no flush is requested. Practically, this just means that we'll call NativeAnimatedModule methods N times at once, at the end of a render loop, instead of N times smeared throughout the render loop.
(2) Additionally, instead of calling N methods, we create multi-operation argument buffer and call a single NativeAnimatedModule API, which should essentially throttle NativeAnimatedModule API calls to once-ish per frame. On the native side, this also reduces a lot of overhead associated with scheduling work on the UI thread (we schedule 1 function to run on the UI thread and perform N operations, as opposed to scheduling N functions to run on the UI thread).
TODO:
- implement stubs for iOS
- write gating code so this can be properly tested in VR and in fb4a
Changelog: [Internal]
Reviewed By: genkikondo
Differential Revision: D36338606
fbshipit-source-id: 29ac949b53b874683128a76525586c22def3143b
Summary:
Because of the disconnect between the ReactJS render loop and Animated nodes, we don't know when a render loop begins or ends. Historically we haven't cared about that much,
but now for perf reasons we're attempting to batch them. Scheduling a function to execute at the end of the runloop and canceling until nothing interrupts it achieves that.
Impact seems fairly minimal and this should work everywhere (android, ios, etc) but we may want to gate the behavior as it *could* change things in surprising ways.
Changelog: [Internal]
Reviewed By: genkikondo
Differential Revision: D36338621
fbshipit-source-id: 48e52a1b2e2bcfb3ef13d3abd38d735967356de7
Summary:
This patches a loophole in the logic that caused some operations to execute immediately and some to be deferred, even within the same render loop. This caused the non-queued operations to be executed out of order. Instead, if an operation is created and a queued exists, we just push the operation to the end of the queue so ordering is preserved.
Changelog: [Internal]
Reviewed By: javache
Differential Revision: D36379125
fbshipit-source-id: d9f63f4d47d8453d51add61763b7b9c74ffe9d88
Summary:
Small win: if the queue is empty we shouldn't start/stop the batch.
Changelog: [Internal]
Reviewed By: rshest
Differential Revision: D36298399
fbshipit-source-id: b43c07994ba28b4c890fe52af4e81c265a3b8ac7
Summary:
We are working on making the empty object literal `{}` have the type `{}` - i.e. exact empty object - rather than being unsealed.
Some manual fixes, in particular to React Native code, which is used and can be synced to other repos (e.g. WWW).
With these changes, error diff in Xplat is down to ~1990 errors
Note that after I roll out `exact_empty_objects`, I'll codemod all the `{...null}` (the only way to get an exact empty object currently) back to `{}`
Changelog: [Internal]
Reviewed By: SamChou19815
Differential Revision: D36142838
fbshipit-source-id: 054caf370db230f42a4c5f5706c88979ef246537
Summary:
We are working on making the empty object literal `{}` have the type `{}` - i.e. exact empty object - rather than being unsealed.
Making this change exposes a variety of errors. We can prevent these errors by annotating what we want the type of the empty object to be.
Reduces Xplat error diff to 2.3k
- Announcement: [post](https://fb.workplace.com/groups/flowlang/posts/903386663600331)
- Support group: [Flow Support](https://fb.workplace.com/groups/flow)
drop-conflicts
Format:
```
arc f
```
Sort imports
```
hg l -n | xargs js1 lint --fix --rule 'fb-tools/sort-requires'
```
Changelog: [Internal]
Reviewed By: samwgoldman
Differential Revision: D36086696
fbshipit-source-id: 90447279f2e6e38f44189b74ec0297719f7adf58
Summary:
Changelog:
[General][Fixed] - Improved Flow type inference in Animated `.interpolate()`
Improves the ergonomics of `.interpolate()` by allowing Flow to infer the correct type for `outputRange`. This is achieved by adding a new type parameter `OutputT` to `interpolate()` (and `Animated.Interpolation` and `InterpolationConfigType`), which Flow infers as either `number` or `string` based on usage.
Admittedly, at the call site, this is not that much safer compared to something like `outputRange: $ReadOnlyArray<number | string>`, but it does document the intent of the API a bit better and provide some downstream type safety. For example, we can now express `Animated.Number` (D35869375) more precisely by excluding string-valued interpolation nodes.
Reviewed By: javache
Differential Revision: D35869725
fbshipit-source-id: e03ec22e9b3368ee196b392af011062ac99d8bb9
Summary:
Changelog: [General][Added] - Add `Animated.Numeric` Flow type
Adds a Flow type to represent the various Animated node types that evaluate to numeric values and can be `interpolate()`d.
I'm including `AnimatedInterpolation` as "numeric" here even though it can technically evaluate either to a number or to a string, depending on its config. Note that calling `interpolate()` on a string-valued `AnimatedInterpolation` is a runtime error.
In a future diff, I'm planning to add a type argument to `AnimatedInterpolation` (and its config type), at which point we can refine `Animated.Numeric` to correctly include only `AnimatedInterpolation<number>`.
Reviewed By: javache
Differential Revision: D35869375
fbshipit-source-id: 2ff6754f1a5abc68c9da2c6836872c2022b25676
Summary:
This drastically improves `Animated.interpolate` performance when `inputRange` has a considerable amount of elements (~100 in my tests).
For instance in `ActivityIndicator` inside `react-native-paper`, the input has 144 elements https://github.com/callstack/react-native-paper/blob/main/src/components/ActivityIndicator.tsx#L170. `react-native-elements` has 9k stars, so I'm assuming this is widely used.
### Cause
The reason for the performance drop is that if we assume `n` to be the size of the range, calculating `'inputRange must be monotonically non-decreasing ' + arr` essentially calculates `arr.toString()` which has O(n) complexity.
Since it is recalculated in a for loop, we end up with `checkValidInputRange` having a O(n²) complexity. Which means ~10k operations if the array has a size close to 100.
## Changelog
[General] [Fixed] - Fix performance issue on Animated.interpolate with big input range
Pull Request resolved: https://github.com/facebook/react-native/pull/33598
Test Plan:
[Here's a repo](https://github.com/Almouro/AnimatedInterpolationRepro) reproducing the issue.
The branch `fix` includes the fix.
Clicking `Interpolate` runs:
```js
new Animated.Value(0).interpolate({
inputRange: Array(144)
.fill()
.map((_, i) => 1 / (i + 1))
.reverse(),
outputRange: Array(144)
.fill()
.map((_, i) => 1 / (i + 1))
```
Here's a comparison of JS thread perf before the fix and after the fix:
- on a Samsung J3 2017 (lower end)
- using Flipper and https://github.com/bamlab/react-native-performance)
- ` __DEV__` mode deactivated
- clicking the button and waiting 15s
| Before | After |
|----------|:-------------:|
|  | |
The error still throws if `inputRange` is incorrect:
<img width="517" alt="image" src="https://user-images.githubusercontent.com/4534323/162439219-6ce120ae-98e5-496b-899a-492978689d6d.png">
However if `__DEV__` mode is deactivated, no error is thrown
Reviewed By: yungsters
Differential Revision: D35507441
Pulled By: javache
fbshipit-source-id: 36ac49422f7a42d247130c42d12248b2be1232c6
Summary:
Before, when we called setValue with a PlatformColor, we unnecessarily called setValue on all component AnimatedValues before updateAnimatedNodeConfig.
This diff also fixes a bug where if we set a PlatformColor as the initial color, calling setValue with a non-PlatformColor would not have any effect. The fix is to reset AnimatedColor.nativeColor to null upon calling setValue.
Changelog:
[Internal] Optimize AnimatedColor when setting platform color
Reviewed By: javache
Differential Revision: D34187540
fbshipit-source-id: a0005d13f392a858d2eade912f2353f67eec1fd9
Summary:
Now that animating color styles using native driver is supported on both Android and iOS, add color styles to the allowlist in NativeAnimatedHelper.
Changelog:
[General][Added] - Allow color styles to be animated using native driver
Reviewed By: mdvacca
Differential Revision: D34148038
fbshipit-source-id: c20dc149b805ec691a3936a77ab130fb4477a4c3
Summary:
In order to support AnimatedColor.setValue for platform colors, we need to pass the platform color object to the native animated node which will then resolve and apply the color.
Thus, the approach is:
- Add a new API updateAnimatedNodeConfig to NativeAnimatedModule
- [JS] On AnimatedColor.setValue, if the value is a platform color, then we call updateAnimatedNodeConfig
- [Android] We introduce AnimatedNodeWithUpdateableConfig interface with a method updateConfig. On ColorAnimatedNode.java, we use updateConfig to resolve and apply the color
Changelog:
[Internal][Fixed] - Use context from view when resolving platform color
Reviewed By: javache, mdvacca
Differential Revision: D34025193
fbshipit-source-id: 8b368f6b7cb2cf7cebe8b66461cd4185cbadd44c
Summary:
Changelog:
[General] [Changed] Type the argument of Animated.interpolate as read-only
Reviewed By: javache
Differential Revision: D33950698
fbshipit-source-id: b959d34eb9752358f4a8ba1d290b56c099f535e0
Summary:
The JS-side animated node values were not being updated on AnimatedValue (and thus AnimatedValueXY); however, the native event "onAnimatedValueUpdate" is being handled properly in AnimatedNode. It turns out that single underscore prefixed methods are obfuscated at FB. And thus AnimatedValue._onAnimatedValueUpdateReceived was not getting called. Changing the method name to double underscore as a way to denote "protected" fixes the issue.
Changelog:
[General][Fixed] - JS animated node value updates properly when listener is attached
Reviewed By: yungsters
Differential Revision: D33962038
fbshipit-source-id: c4f60e1f1ccc0cef3e65b89034bdb91376a26416
Summary:
Adds support for platform colors in AnimatedColor.
Passes the processed native color object to the native ColorAnimatedNode via the native config; ColorAnimatedNode then uses ColorPropConverter.getColor to resolve the resource path.
Note: setting a platform color via setValue on an existing AnimatedColor is not supported yet
Changelog:
[Android][Added] - Support platform color with AnimatedColor
Reviewed By: yungsters
Differential Revision: D33922266
fbshipit-source-id: 04d39a5ce0872b31d06ffbd4639d2f2213cf3314
Summary:
Adds support for Animated.Color with native driver for Android. Reads the native config for the rbga channel AnimatedNodes, and on update(), converts the values into an integer (0xaarrggbb)
Followup changes will include support for iOS and platform colors.
Changelog:
[Android][Added] - Support running animations with AnimatedColor with native driver
Reviewed By: javache
Differential Revision: D33833600
fbshipit-source-id: 2bf05c9715b603cf014ace09e9308b2bfd67f30a
Summary:
In addition to rgba values, allow creating Animated.Color with a string color.
Followup changes will include support for platform colors and native driver.
Changelog:
[General][Added] - Support string color values in Animated.Color
Reviewed By: javache
Differential Revision: D33810717
fbshipit-source-id: 208bc2675b6153a515fbf2122da15a065c473e73
Summary:
Creates Animated.Color for animating color props.
Implement AnimatedColor, which basically consists of 4 AnimatedValues (along the same vein as ValueXY) which allows us to just use AnimatedValue's interpolation. Provides a string color value of shape 'rgba(r, g, b, a)'
AnimationNode DAG looks like:
{F696076974}
Followup changes will include support for string color values, platform colors, and native driver.
Changelog:
[General][Added] - New Animated.Color node
Reviewed By: mdvacca
Differential Revision: D33778456
fbshipit-source-id: 83ddbc955156bf589c864f229a5f83fe6875fd0e
Summary:
In Animated, when a toValue of AnimatedValue (as opposed to a number) is passed in, the [AnimatedValue starts tracking via AnimatedTracking](https://www.internalfb.com/code/fbsource/[b688f3747a706236fce300636978ed1ca5e4081a]/xplat/js/react-native-github/Libraries/Animated/AnimatedImplementation.js?lines=142) but it doesn't actually start animating even if start() is called on the animation.
This behavior is inconsistent with a toValue of a number, which executes immediately on start(). This diff adds a call to AnimatedTracking.update within AnimatedValue.track, which starts the tracking animation.
Changelog:
[General][Fixed] - Fixes execution of animation when a toValue of AnimatedValue is used.
Reviewed By: JoshuaGross
Differential Revision: D33800373
fbshipit-source-id: 85ee6f51bc2bb2e078b586b076a8d1dfe92c1155
Summary:
`Easing` only has static properties and is never constructed or subclassed, so there doesn't seem to be any reason for it to be a class instead of an object.
as a class, Flow errors about `method-unbinding` on every single use of it.
Changelog: [Internal]
Reviewed By: motiz88
Differential Revision: D33774944
fbshipit-source-id: c0bd2e3d7a78e538f95b88b2b1b12d301c8f590c
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/32736
The ability to pass an additional property bag to further configure NativeAnimated is useful for a few reasons, e.g., experimentation with multiple implementations of the NativeAnimated module.
The specific use case this solves is on react-native-windows, where there are two underlying animation graph options, one "optimized" animation graph that uses UI.Composition, and another similar to the approach to iOS and Android that uses a frame rendering callback.
The platform configuration can be supplied to the animation node when `useNativeDriver` is set to `true`, and we pass the platform configuration object to the connected AnimatedValue and all it's children.
Changelog:
[General][Added] - Option to supply `platformConfig` to NativeAnimated
Reviewed By: yungsters
Differential Revision: D32988285
fbshipit-source-id: ab8a7bbf197573fc9e9a4737c255f124321295ac
Summary:
Flow currently allows duplicate members on classes. At runtime the "last" member wins out and all previous values for the member are discarded.
This diff manually removes duplicate members, and fixes resulting flow errors by converting methods to arrow function properties.
Reviewed By: pieterv
Differential Revision: D33664966
fbshipit-source-id: 0f712ac96af4df593c0918fcbadd70624ddde4a6
Summary:
AnimatedValue fires a callback with the current value (raw value + offset) after calling it's `stopAnimation` method. The `_value` field on the `AnimatedValue` node is not necessarily kept in sync with the NativeAnimated value node, so the value provided to the callback may be out of sync.
This change checks if the `AnimatedValue` is a native node and passes the callback to the `NativeAnimatedAPI.getValue` callback, defaulting to the previous current JS node state if the node is not native.
Changelog:
[General][Fixed] - AnimatedValue.stopAnimation callback with correct value for NativeAnimated
Reviewed By: yungsters
Differential Revision: D32968572
fbshipit-source-id: b83f86eabe5456f762a15bc29cacb43f84513f6c
Summary:
This diff runs the codemod to add type annotations to function parameters in preparation for Flow's local type inference (LTI) project. I ran the codemod over xplat/js and reverted any files that had flow errors in them. See the list of commands run to see the regeneration of various files.
Changelog:
[Internal][Changed] - Added type annotations
Reviewed By: yungsters
Differential Revision: D32075270
fbshipit-source-id: 6a9cd85aab120b4d9e690bac142a415525dbf298
Summary:
This diff makes the manual changes necessary to fix many of the errors in the stacked diff codemod.
See https://fb.workplace.com/groups/flowlang/posts/917522612186736 for details on this effort.
Reviewed By: bradzacher
Differential Revision: D31615035
fbshipit-source-id: 179b2df516833d59873b9003350f81eb4a6b4e9d
Summary:
Single and composite animations were handled inconsistently in AnimatedMock. Also added a guard to prevent callbacks from triggering additional animations, since we had a test-scenario that did exactly that.
Changelog:
[General][Fixed] - Composite animations will now be ran immediately when the app is in testing mode
Reviewed By: yungsters
Differential Revision: D31826967
fbshipit-source-id: a6416b42e227fe79f5c3a55a9c51beb8451874f8
Summary:
The documentation of back easing contains a old link that
is now stale. I'm updating it to link to https://easings.net/#easeInBack
Fixes https://github.com/facebook/react-native/issues/32419
Changelog:
[Android] [Fixed] - Fixes documentation for back Easing animation
Reviewed By: hramos
Differential Revision: D31728560
fbshipit-source-id: 99f7aa60d3748af5429b4ae1aa6cbd79326c5fe6
Summary:
Implement par of the discussion https://github.com/react-native-community/discussions-and-proposals/discussions/411, except the `.nvmrc` part, this includes:
- Setting `.ruby-version` in the main project and also `template/`
- Fixing the CocoaPods version with a project-level `Gemfile` and also `template/Gemfile`
- Using all `pod` executions from `bundle exec pod`, using the determined version
- Script to manage and update the ruby version
## Changelog
[iOS] [Added] - Gemfile with CocoaPods 1.11 and ruby-version (2.7.4)
Pull Request resolved: https://github.com/facebook/react-native/pull/32303
Test Plan: Build for iOS and run all CircleCI tests to see if nothing changed
Reviewed By: RSNara
Differential Revision: D31344686
Pulled By: fkgozali
fbshipit-source-id: 25c63131ca9b16d3cf6341019548e0d63bdcaefe
Summary:
When we were iterating on the Fabric renderer, animated components went through some iteration to ensure that animated shadow nodes were not flattened away. At the time, `collapsable` was not supported on iOS, even in Fabric, because the legacy renderer would not publish the `collapsable` prop on the view config.
This has since been fixed and `collapsable` is supported on both Android and iOS. We no longer need the `nativeID` workaround to prevent view flattening.
For use cases of the JavaScript driver and legacy renderers, this change will cause views which used to be flattened to no longer be flattened. This seems like an appropriate change considering the direction that we are moving (in which everything is eventually transitioned to using the Fabric renderer).
Changelog:
[Android][Changed] - Native views backing Animated.View (w/ JavaScript-driven animations) will no longer be flattened; this should be a transparent change.
Reviewed By: lunaleaps, mdvacca
Differential Revision: D31223031
fbshipit-source-id: 48dc63471eef406f4c215bfea0b3ef82a05d4b24
Summary:
Changelog: [Internal]
This diff add types to some of the common globals so uses of
them through `global` are now typed.
All the globals are marked as read-only for their intented uses.
However, some of them do have write cites (mostly are in tests to
deliberately set up a special test environment). Those write cites
are considered as "necessary evil" and annotated as `FlowFixMe`.
Reviewed By: yungsters
Differential Revision: D30158145
fbshipit-source-id: 93a99063361a4b7a1e33d9fc97a661be30a4d8f9
Summary:
Changelog: [internal]
Make sure the order of call is preserved for `NativeAnimatedModule`. The order of calls to NativeAnimatedModule needs to be preserved because its internals depend on it. For example, if you `getValue` is called before `createAnimatedNode`, it causes a crash.
To resolve it, we need to enqueue `getValue` onto operationQueue.
Reviewed By: JoshuaGross
Differential Revision: D30035911
fbshipit-source-id: bbd698a96cada5d2b1312a1a689ca99b04a07cdc
Summary:
Add animation queuing back into createAnimatedComponent_EXPERIMENTAL.js, which is a concurrent-safe version of createAnimatedComponent.
T93269035 for details on why this is needed.
# How does this work?
In the old createAnimatedComponent, Animations were queued by calling `setWaitingForIdentifier` before render, and then calling `unsetWaitingForIdentifier` after render.
In this diff, instead we are calling `setWaitingForIdentifier` in an `useLayoutEffect` before calling `useAnimatedProps`, and we are calling `unsetWaitingForIdentifier` in a `useEffect` after `useAnimatedProps`. So the ordering for the effects are:
1. `useLayoutEffect` with `setWaiting`
2. `useLayoutEffect`s in `useAnimatedProps`
3. `useEffect`s in `useAnimatedProps`
4. `useEffect` with `unsetWaiting`.
There's a React guarantee that **if one effect is called, all of them will be called**, so we don't have a concern about the queue getting locked.
## **Main concerns:**
1. This works in my test cases, but it's not the same behavior as the old createAnimatedComponent (which is wait before and unset wait after render). This may still be ok because the relevant side effects in render from that component have been moved to `useLayoutEffect` or `useEffect` in `useAnimatedProps` (so the ordering is still the same?).
2. I'm not sure about the ordering of `onLayoutEffect`, `onLayout` callbacks, and `useEffect`. createAnimatedComponent_EXPERIMENTAL doesn't use `onLayout`, but with this new method of queuing, **`onLayout` calls will likely be called before the animation queue has been flushed**. It's not clear to me whether this is bad.
Changelog: [Internal]
Reviewed By: yungsters
Differential Revision: D29467458
fbshipit-source-id: 2be23a8968404526d0fa394a7879fda8b5ffbfdc
Summary: Changelog: [Internal] - Animated.event from my limited understanding attaches Animated.Values to native views. In terms of animation, Animated.Values are already handled by AnimatedMock to skip interpolation.
Reviewed By: GijsWeterings
Differential Revision: D29241590
fbshipit-source-id: 98650883dad53d6f77dbc398ba0cac903194deca
Summary:
This pre-suppresses the 154 error diff ahead of its release, since it is large.
Changelog: [Internal]
Reviewed By: samwgoldman
Differential Revision: D29065246
fbshipit-source-id: f418041305a46df410dcbe3d9a4db81a61ac7014
Summary:
Creates a `useAnimatedProps` hook that is compatible with concurrent mode, and uses this in `createAnimatedComponent_EXPERIMENTAL`.
Changelog:
[Internal]
Reviewed By: lunaleaps
Differential Revision: D28390393
fbshipit-source-id: d8aa471507a5d096832b93caf63a24f71733deda
Summary:
Creates an experimental stub implementation of `createAnimatedComponent` to be implemented in future commits.
Changelog:
[Internal]
Reviewed By: lunaleaps, kacieb
Differential Revision: D28799738
fbshipit-source-id: dc3fbee557db353de6807bd87561f8f372d7cab5
Summary:
Sets up an injection mechanism for experimenting in production with an alternate implementation of `createAnimatedComponent`.
This will be used to implement and refine a new `createAnimatedComponent` that is compatible with concurrent rendering.
Changelog:
[Internal]
Reviewed By: lunaleaps
Differential Revision: D28799739
fbshipit-source-id: 46ba2dd6137f7bf73ce8a659698533ed3985516f
Summary:
This pre-suppresses the 153 error diff ahead of its release, since it is large.
Changelog: [Internal]
Reviewed By: mroch
Differential Revision: D28754374
fbshipit-source-id: 1806f53bc7d804644d434583a2dcd6da63d00328