Save 37% off PRO during our Black Friday Sale! »

Going Over The Speed Limit - Synchronous Rendering in React Native

Fda8c6c2e77ab98f85e85f99656859a0?s=47 Tal Kol
September 06, 2017

Going Over The Speed Limit - Synchronous Rendering in React Native

* Given in React Native EU (Poland) on Sept 6, 2017

Asynchronous rendering is one of the core principles of React. On the web, the ability to batch updates and work on a virtual DOM proved to be key factors in improving rendering performance. The same architecture seems to do miracles in React Native and gives JavaScript the performance boost needed to render native views effectively.

This benefit of React Native is also its greatest drawback. For certain types of problems in native mobile, asynchronous rendering introduces an overhead that is almost impossible to bridge. List views are a good example, as even the best implementation to date, FlatList, struggles to keep up with the fill rate of the most naive list implementation in pure native.

Is it possible to introduce synchronous rendering to React Native and tackle this category of problems from a different direction?

Fda8c6c2e77ab98f85e85f99656859a0?s=128

Tal Kol

September 06, 2017
Tweet

Transcript

  1. Synchronous Rendering in React Native GOING OVER THE SPEED LIMIT

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

  3. Performance, Are We There Yet? 01

  4. The Pepsi Challenge WHICH ONE USES REACT NATIVE?

  5. Eliminating the gaps § Animations Declarative animations with Animated +

    native driver § Navigation Wix react-native-navigation + Airbnb native-navigation § Gestures Krzysztof Magiera’s new native gesture system § Interactions My react-native-interactable library from React Conf
  6. Flicker when pushing a new screen 1

  7. Flicker when fast scrolling down lists (fill-rate) 2

  8. Easy to Fix? APPARENTLY IT’S NOT SO SIMPLE The declarative

    trick doesn’t work here… An inherent issue with how React works
  9. To Block or Not To Block 02

  10. The JavaScript Realm The Native Realm The Bridge React Native

    Architecture JavaScript Thread Main UI Thread
  11. Alternative 1: Blocking JavaScript Thread Main UI Thread A A

    B B
  12. Alternative 2: Non-Blocking JavaScript Thread Main UI Thread A A

    B B
  13. React for Web THE CHOICE HAS ALREADY BEEN MADE THEN

    Similar problem, DOM == native realm Performance gains by non-blocking (shadow DOM)
  14. React rendering is asynchronous by design

  15. User scrolls N pixels down the list Prepare New Row

    Scroll Event Create View Redraw Content New uninitialized row drawn as white space New row drawn with correct content React Render
  16. Circumventing Asynchronicity 03

  17. RCTRootView React Component Tree

  18. RCTRootView API § create

  19. User pushes a new screen React Root Init Create Event

    Create Views Create RCTRootView New uninitialized screen drawn as white space New screen drawn with correct content React Render
  20. We want to support a synchronous root view

  21. RCTSyncRootView React Component Tree

  22. RCTSyncRootView API § create § update props

  23. User pushes a new screen Create Views Create RCTSyncRootView New

    screen drawn with correct content React Render JavaScript initialization (load) Magic Store Recipe Magic Use Recipe
  24. Synchronous render resolves the flicker!

  25. User scrolls N pixels down the list Prepare New Row

    Scroll Event Create View Redraw Content New uninitialized row drawn as white space New row drawn with correct content React Render
  26. User scrolls N pixels down the list Create View Recycle

    Old Row New row drawn with correct content React Render JavaScript initialization (load) Magic Store Recipe Magic Use Recipe
  27. Implementing The Magic Parts 04

  28. Hacking the Reconciler TIME TO LOOK UNDER THE HOOD How

    does React render native views? We’ll use this process to create our recipe!
  29. render component

  30. Storing the Recipe ON JAVASCRIPT INITIALIZATION Manually call RN.render from

    SyncRegistry Swizzle UIManager funcs with store stubs
  31. render component

  32. Using the Recipe WHEN RCTSyncRootView IS CREATED OR UPDATED On

    demand, execute commands from native Instantiate native views without the bridge!
  33. Limitations § Only “declarative” components § No JavaScript code in

    render func § Prop updates can’t change the tree
  34. None
  35. Proof of Concept Get Full Code github.com/wix/rn-synchronous-render

  36. Thanks. linkedin/talkol github.com/talkol @koltal talkol@wix.com medium.com/@talkol @koltal