software-mansion / react-native-reanimated

React Native's Animated library reimplemented
https://docs.swmansion.com/react-native-reanimated/
MIT License
8.84k stars 1.29k forks source link

useAnimatedStyle height blocked by main thread, transform is not. #1123

Closed kyle-ssg closed 4 years ago

kyle-ssg commented 4 years ago

Description

If I block the main thread with an intensive function, animations only seem to be non-blocking if I use transform rather than height. It was my understanding from the documentation that although some styles are more intensive to compute it would all happen on the UI thread.

"supports animations of all native properties without generating any load on the main JavaScript thread (including layout properties like width, flex, etc.)."

However, I have a very basic scenario that seems to disprove this.

Using transform

Using height

Screenshots

Steps To Reproduce

  1. Add the following to a component that has a gesture handler
  useEffect(() => {
    setTimeout(() => {
      function mySlowFunction(baseNumber) {
        console.warn('mySlowFunction');
        let result = 0;
        for (var i = Math.pow(baseNumber, 7); i >= 0; i--) {
          result += Math.atan(i) * Math.tan(i);
        };
        console.warn('mySlowFunction');
      }

      mySlowFunction(100); // higher number => more iterations => slower

    }, 2000);
  }, []);

The following is blocked by the main thread

  const animatedHeightStyle = useAnimatedStyle(() => ({
    height: animatedHeight.value,
  }));

Where as this is not

  const animatedHeightStyle = useAnimatedStyle(() => ({
    transform: [{translateY:animatedHeight.value}],
  }));

Expected behavior

I'd expect a blocked main thread to have no effect regardless of style in useAnimatedStyle.

Actual behavior

Using height rather than transform causes a blocked animation.

Snack or minimal code example

VerticalSlider in:

https://github.com/kyle-ssg/reanimated2-experiments

The file in question

https://github.com/kyle-ssg/reanimated2-experiments/blob/master/App/components/VerticalSlider.tsx

Package versions

   "react": "16.13.1",
    "react-native": "0.63.1",
    "react-native-reanimated": "2.0.0-alpha.5",
terrysahaidak commented 4 years ago

All the UI properties (which don't require layout recalculation) are updated on UI Thread. Layout properties are asynchronously updated on Main Thread - don't confuse it with JS Thread which you're blocking in this example.

I remember I tried to test similar example and it worked perfectly back then.

Might be some regression.

kyle-ssg commented 4 years ago

Sorry yep I'll try get the terminology right for future reference! I'm about to test a similar case with useAnimatedProps, but yeah it's definitely getting blocked based on using height vs transform, replication should be very straight forward.

terrysahaidak commented 4 years ago

Could you check the CPU usage during this test?