Upgrade to Pro — share decks privately, control downloads, hide ads and more …

React Native ❤ 60FPS Improving React Native animations - ReactEurope 2016

React Native ❤ 60FPS Improving React Native animations - ReactEurope 2016

Animations are one of the most important elements of modern, well-crafted mobile apps. Animation effects possible to achieve using native SDKs exceed by far the capabilities of mobile browsers, hence based on the quality of animations it is easy to tell the difference between truly native apps and ones that run in a webview.

React Native provides several APIs for handling animations (layout animations, native navigator, Animated.js library). Some of them lets you directly leverage native SDK capabilities, others require round-trips over native-to-JS bridge. We will dive a little into implementation details of each of those methods to explain their limitations. I will also discuss native-animated-driver (the project I've been recently working on), and give some tips on how to make your React-Native app stay at 60FPS.

Krzysztof Magiera

June 02, 2016

More Decks by Krzysztof Magiera

Other Decks in Technology


  1. React Native ❤ 60FPS Improving React Native animations Krzysztof Magiera

    (@kzzzf) krzys@swmansion.com
  2. WHY DO WE ANIMATE? Transition, Focus, Fun



  5. NATIVE COMPONENTS ANIMATIONS <TouchableNativeFeedback/>


  7. NATIVE COMPONENTS ANIMATIONS PROS CONS • maximum performance • platform-specific

    behaviour “by default” • very little work • very limited set of components • often impossible to customise
  8. LayoutAnimation.spring(); this.setState({...}); LAYOUT ANIMATIONS

  9. LAYOUT ANIMATIONS JS Thread LayoutAnimation.spring(); UIManager.createView(...); UIManager.addChildren(...); Native Thread UI

    Thread applyUpdates(); runLayout(); ANIMATED_BLOCK_START; updateX(from: 180, to: 250); ANIMATED_BLOCK_END;
  10. LAYOUT ANIMATIONS PROS CONS • native performance • very easy

    API • works for layout properties only • non interruptible
  11. ANIMATED.JS “focuses on declarative relationships between input and outputs”

  12. ANIMATED.JS (basics) var someValue = new Animated.Value(0); // can be

    kept in the component state return ( <Animated.View style={{opacity: someValue}}> <Text>Hello!</Text> </Animated.View> ); Animated.spring( someValue, { toValue: 1, friction: 0.5, } ).start();
  13. ANIMATED.JS (basics) var anotherValue = new Animated.Value(-200); var product =

    Animated.multiply(interpolatedValue, anotherValue); var interpolatedValue = someValue.interpolate({ inputRange: [0, 100], outputRange: [0, 1], });
  14. ANIMATED.JS (implementation)

  15. someValue: 0 anotherValue: -200 interpoleted style <View/> ANIMATED.JS (implementation)

  16. someValue: 0 anotherValue: -200 in requestAnimationFrame() ANIMATED.JS (implementation)

  17. someValue: 0 anotherValue: -200 in ANIMATED.JS (implementation) <ScrollView onScroll={Animated.event( [{nativeEvent:

    {contentOffset: {y: someValue}}}] )} /> event handleOnScroll()
  18. ANIMATED.JS PROS CONS • very flexible • allows for defining

    gesture interaction • best performance when not animating layout properties • difficult to express layout animations – complementary API is needed • gesture reaction latency • overloading JS thread
  19. ASYNC FATE Thread Thread UI I’m free and can do

    whatever I want but I won’t be blocking the UI Render some stuff with React and then send render commands to the UI Thread RENDER, RENDERRR..
  20. ASYNC FATE Thread Thread UI Hey! Touch event! Handle touch

    – maybe render sth RENDER, RENDERRR..
  21. ASYNC FATE Thread Thread UI Handle touch – maybe render

    sth RENDER, RENDERRR.. f1 f2 f3 input compose sorry man, have to compose the frame … input compose input VSYNC
  22. ANIMATED.JS Your frame just left – next one is in

  23. None
  24. ANIMATED.JS InteractionManager https://facebook.github.io/react-native/docs/interactionmanager.html

  25. ANIMATED.JS “focuses on declarative relationships between input and outputs”

  26. ANIMATED.JS declarative declarative


  28. OFFLOADING ANIMATIONS generateAnimatedGraph() runAnimationLoopOnUIThread()

  29. Animated.spring( someValue, { toValue: 1, friction: 0.5, useNativeDriver: true, }

    ).start(); OFFLOADING ANIMATIONS LIMITATIONS • implemented on Android only • only a subset of Animated.js has been implemented • animating layout properties is not supported • using value update handlers will still require JS roundtrip • single value cannot be used for animating both using native driver and using JS driver https://github.com/facebook/react-native/pull/7884
  30. Thank you! Krzysztof Magiera krzys@swmansion.com @kzzzf