What's all the fuss about React Native?

The good, the bad and the Android

React Native in a nutshell

Learn once, write anywhere vs. write once, run anywhere

No iOS dev

No Android dev

Just a mobile dev

Which leads us from...

Through...

To...

~80% code shared between both platforms

React Native in depth

So I started digging...

And at one point I got it

So... starting from the top

so-called "bridging"

To batch or not to batch

Facebook engineering blog: (...) performance analysis showed the overhead of JS calls to native was not a bottleneck: In fact, delaying UI or cache read calls to batch them with later calls also delayed work on the native thread, which harmed performance. In other cases, like the Relay cache read fetching data for multiple keys, batching proved to be a significant improvement.

It all comes down to 3 threads

UI Event Queue Native Modules Event Queue JS Event Queue
("main thread") responsible for handling user actions, e.g. touch events responsible for receiving calls from JS Event Queue, recalculating layout based on new values and sending back to UI thread (and bunch of other stuff) responsible for handling UI actions, e.g. events and calling native modules

Example

And it works

both async

and in 60 fps

To sum up

  • 3 threads (UI a.k.a main thread, Native Modules thread and JS thread)
  • async communication via bridge (bridging)
  • batching some calls, for instance reading from cache and debatching others, for instance layout changes
  • easy code integration: access to both JS code from Obj-C/Java and native code from JS
  • interactions in 60 fps "almost" out of the box

Why almost?

Animations in RN

Native animations (e.g. Lottie) - limited control

LayoutAnimation - preferred when animating affects group of elements

Animated (kinda similar to react-motion) - can be offloaded by setting useNativeDriver (still not perfect)

InteractionManager - for delaying expensive computations

Expensive computations

Example: pushing routes, i.e. transition between heavy components

componentDidMount() {
    InteractionManager.runAfterInteractions(() => {
        this.setState({isReady: true});
    });
}

We could have created HoC with:

RN: the good parts

If you already know React the learning curve is very shallow

Hot reloading

Dev menu: inspect + perf

Community

dozens of free packages (with huge ones like react-native-maps or Gifted Chat) including UI libs:  react-native-elements & NativeBase

Community

Sam Okoro

https://github.com/VctrySam

Community

bootstrap your app with Exponent in minutes with sample tabs, routing, tests and share a link to run on a mobile device

Painless testing with Jest

 

Snapshot testing

Unfortunately some things still suck

  • Many breaking changes in layout leading to non-trivial upgrades
  • Android version slowly becoming mature, but there are still many bugs to fix, e.g. broken zIndex, onContentSizeChange in multiline TextInput
  • Missing features, e.g. Android PN, proper text selection
  • Documentation is not always up-to-date, so inspecting react-native code becomes a must

Special thanks to

 

https://code.facebook.com/posts/895897210527114/dive-into-react-native-performance/

https://tadeuzagallo.com/blog/react-native-bridge/

...and hundreds of issues on GitHub that help understand what's going on when dealing with edge cases

rn

By Przemek Murawski