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

Moving Beyond Animations to User Interactions at 60 FPS

Fda8c6c2e77ab98f85e85f99656859a0?s=47 Tal Kol
March 13, 2017

Moving Beyond Animations to User Interactions at 60 FPS

* Given in ReactConf 2017 in Santa Clara on March 13, 2017

The async nature of the React Native bridge incurs an inherent performance penalty. This traditionally prevented JavaScript code to run at high framerates. The most noticeable challenge is animations in JS, which aren't guaranteed to run at 60 FPS.

Modern animation libraries for React Native, like Animated, tackle this challenge with a declarative approach. In order to minimize passes over the bridge, animations are declared in JS but executed by a native driver on the other side.

User interactions are a step further than animations. Interactions require UI to continuously react to the user's gestures. Consider a drawer opening with buttons appearing gradually as it is being dragged, or a card being swiped away. Unfortunately, those are still lagging behind.

We'll demonstrate JS implementations for complex interactions that run at 60 FPS. We'll also demonstrate how to generalize this approach with a library. Similar to Animated - just aimed at interactions, not animations.

Fda8c6c2e77ab98f85e85f99656859a0?s=128

Tal Kol

March 13, 2017
Tweet

Transcript

  1. Moving Beyond Animations to User Interactions at 60 FPS PUSHING

    BOUNDARIES WITH REACT NATIVE TAL KOL Head of Mobile Engineering at Wix.com |
  2. @koltal Passionate about React Native at Hi.

  3. Can React Native Cross The Last Mile? 01

  4. What makes great apps? THE MAGICAL NUANCES THAT SET YOU

    APART Fluid animations at 60 FPS Dynamic user interactions that mimic reality
  5. ListView Row Actions 1

  6. Swipeable Cards 2

  7. Collapsible Views 3

  8. Sliding Panels & Drawers 4

  9. Implement in JavaScript?

  10. _handlePanMove setValue TouchEvent(x1) UpdateView Frame 1 _handlePanMove setValue TouchEvent(x2) Frame

    2 JavaScript Native Bridge
  11. Implement in native? ONE SURE WAY TO REDUCE BRIDGE TRAFFIC

    That's what we do in our app (as OSS) Native skillset is required, the 10% rule
  12. Learn from animations § Similar problem JS animations are noisy

    over the bridge § Animated library emerged as the way to deal with this § Declarative API to specify the behavior in JS at once § JS/native driver takes the declaration and runs frame by frame
  13. Declarative API is how we cross the last mile

  14. Declarative API For User Interactions 02

  15. API – phase 1 § horizontal / vertical § snapping

    points § friction
  16. ListView Row Actions 1 x = 0 x = 100

    horizontal: true snapPoints: [ {x: 0}, {x: 100} ] friction: 0.7
  17. Swipeable Cards 2 x = -360 x = 0 horizontal:

    true snapPoints: [ {x: -360} {x: 0}, {x: 360} ] friction: 0.6
  18. Collapsible Views 3 y = 250 y = 0 vertical:

    true snapPoints: [ {y: 0}, {y: 250} ] friction: 0.8
  19. Sliding Panels & Drawers 4 y = 0 vertical: true

    snapPoints: [ {y: 0}, {y: 660} ] friction: 0.5 y = 660
  20. TouchEvent(x1) UpdateView Frame 1 TouchEvent(x2) Frame 2 JavaScript Native Bridge

    Initialize Declare Interaction Initialize Driver UpdateView
  21. Drag with gesture recognizer then animate using spring to closest

    snap point Implement native driver – phase 1
  22. Compute the entire interaction with UIKit Dynamics – a full

    fledged iOS physics engine Implement native driver – phase 2
  23. Physics 101 NEWTON TO THE RESCUE ∆ = 2 −

    1 = − ( ∆ = ∆ = ( ∆
  24. Switch to our own custom physics engine for more control

    and ability to port to Android Implement native driver – phase 3
  25. We're writing a declarative physics engine for React Native

  26. Pushing The Envelope 03

  27. Enrich API – 1 § boundaries § bounce boundaries: {

    bottom: 0, bounce: 0.5 }
  28. Enrich API – 2 § localized forces (friction, springs) friction:

    { value: 0.8, area: {left: 0} }
  29. Enrich API – 3 § animate other views (Animated) d

    = new Animated.Value(0) animatedValueX: d
  30. Enrich API – 4 § gravity § magnetism § events

    § haptics
  31. Enrich API – 4 snapPoints: [ {x: -140}, {x: 140}

    ] gravityPoints: [ {x: 0, y: 200, strength: 8000} ] friction: 0.8 animatedValueY: this.deltaY onStop: this.onStopEvent haptics: true
  32. Judge For Yourself Search app stores for "React Native Interactions"

    Is it really 60 FPS?
  33. Get Full Code github.com/wix/ react-native-interactable Try Demo App Search app

    stores for "React Native Interactions"
  34. Thanks. linkedin/talkol github.com/talkol @koltal talkol@wix.com medium.com/@talkol