Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
React Native: Under the Hood
Search
Alexander Kotliarskyi
June 09, 2015
Programming
31
22k
React Native: Under the Hood
Alexander Kotliarskyi
June 09, 2015
Tweet
Share
More Decks by Alexander Kotliarskyi
See All by Alexander Kotliarskyi
Building Stellar User Experiences with React Native
frantic
2
930
React Native Tutorial - NYC'15
frantic
5
1.4k
Other Decks in Programming
See All in Programming
チームで開発し事業を加速するための"良い"設計の考え方 @ サポーターズCoLab 2025-07-08
agatan
1
420
設計やレビューに悩んでいるPHPerに贈る、クリーンなオブジェクト設計の指針たち
panda_program
6
2.1k
Flutterで備える!Accessibility Nutrition Labels完全ガイド
yuukiw00w
0
160
Claude Code + Container Use と Cursor で作る ローカル並列開発環境のススメ / ccc local dev
kaelaela
9
5.1k
VS Code Update for GitHub Copilot
74th
2
640
「テストは愚直&&網羅的に書くほどよい」という誤解 / Test Smarter, Not Harder
munetoshi
0
170
PicoRuby on Rails
makicamel
2
130
脱Riverpod?fqueryで考える、TanStack Queryライクなアーキテクチャの可能性
ostk0069
0
130
ニーリーにおけるプロダクトエンジニア
nealle
0
830
明示と暗黙 ー PHPとGoの インターフェイスの違いを知る
shimabox
2
510
スタートアップの急成長を支えるプラットフォームエンジニアリングと組織戦略
sutochin26
1
5.6k
RailsGirls IZUMO スポンサーLT
16bitidol
0
180
Featured
See All Featured
Bootstrapping a Software Product
garrettdimon
PRO
307
110k
Speed Design
sergeychernyshev
32
1k
Become a Pro
speakerdeck
PRO
29
5.4k
Making Projects Easy
brettharned
116
6.3k
Learning to Love Humans: Emotional Interface Design
aarron
273
40k
Rails Girls Zürich Keynote
gr2m
95
14k
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
507
140k
Build The Right Thing And Hit Your Dates
maggiecrowley
36
2.8k
Reflections from 52 weeks, 52 projects
jeffersonlam
351
20k
Imperfection Machines: The Place of Print at Facebook
scottboms
267
13k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
231
53k
Bash Introduction
62gerente
613
210k
Transcript
React Native: Under the hood Alex Kotliarskyi Facebook
Plan 1. Why native apps matter? 2. How ReactJS works
3. Running ReactJS on native platforms
Why do we ❤ native apps?
Native Apps • Fast, responsive • Complex gestures and smooth
animations • Consistent with platform
None
Building native apps is hard • Different stacks of technologies
• No knowledge and code sharing • Slow iteration speed • Hard to scale
Web got this right
Web • Different stacks of technologies • No knowledge and
code sharing • Slow iteration speed • Hard to scale HTML / CSS / JS Same code and tech F5 / ⌘R React!
Web apps on the phone are not great • Very
hard to provide smooth experiences • Not designed for complex interactions • Impossible to embed native components
Development experience Awesome apps
React Native
None
UI = ƒ*(data) * No side effects
None
UI = ƒ(count)
UI = ƒ(count) = div( span('Count ' + count), button('Add
+1') )
render() { return (
div( span( 'Count: ' + b(this.state.count) ), button( 'Add +1' ) ) ) }
render() { return (
<div> <span> Count: <b>{this.state.count}</b> </span> <button> Add +1 </button> </div> ) } HTML VirtualDOM
render() { return (
<div> <span> Count: <b>{this.state.count}</b> </span> <button onClick={() => ??? }> Add +1 </button> </div> ) }
TextView text = (TextView)findViewByID(R.layout.label); text.setText('10'); _label.text = @"10"; too
complex Android Objective-C JavaScript document.getElementByID('count').children[1].innerHTML = '10'; $('#counter b').html('10');
render() { var count = this.state.count;
return ( <div> <span> Count: <b>{count}</b> </span> <button onClick={() => ??? }> Add +1 </button> </div> ) }
render() { var count = this.state.count;
return ( <div> <span> Count: <b>{count}</b> </span> <button onClick={() => this.setState({count: count + 1})}> Add +1 </button> </div> ) } setState
setState
<div> <span>
Count: <b>9</b> </span> <button> Add +1 </button> </div> <div> <span> Count: <b>10</b> </span> <button> Add +1 </button> </div> state = {count: 9} state = {count: 10} <b>9</b> <b>9</b> <b>10</b> findDOMNode(b).innerHTML = '10';
Components Browser DOM UIKit Components Components Components VirtualDOM
1. Runtime 2.Base components 3. Calling native functions
ECMAScript 5
JavaScript Core • Part of WebKit project • Open Source
• Ships with iOS Runtime
<div> <span> <img> <View> <Text> <Image>
<ScrollView> <MapView> <TabBar> <DatePicker> ... Base components
create(view, parent, attributes)* update(view, attributes) delete(view) * actually React is
more complex that that
Just call native functions? nope
Synchronous
Native Method JavaScript time Waiting…
JavaScript time Native JavaScript Native
Synchronous Asynchronous
Overhead of every native call
JavaScript time
time JavaScript
Overhead of every native call Batch native calls
Shared mutable data
Native Objects JavaScript Objects
Shared mutable data Exchange serializable messages
Asynchronous Batched Serializable
The Bridge
Native Bridge JavaScript
Native Bridge JavaScript Event (touch, timer, networks, etc.) 1 Collect
data and notify JS 2 Serialized payload 3 Process event 4 Call 0 – ∞ native methods 5 Update UI (if needed) 8 Serialized response 6 Process commands 7
JS is event-driven
Events Commands
Example
• Updates counter • Sends data to web service
render() { return (
<View style={styles.container}> <Text style={styles.value}> {this.state.count} </Text> <Button title="Add +1" onPress={() => this.inc()} /> </View> ); }
inc() { var newCount =
this.state.count + 1; this.setState({count: newCount}); fetch( 'https://api.conunter.io/', { method: 'post', body: 'value=' + newCount } ); }
Native UITouch [_bridge enqueueJSCall:@"EventEmitter.receiveTouches" args:@[@"end", @{@"x": @42, @"y": @106}]]; x,
y, view, ...
Native Bridge JavaScript [ 'EventEmitter', 'receiveTouches', ['end', {'x': 42, 'y':
106}] ] [_bridge enqueueJSCall:@"RCTEventEmitter.receiveTouches" args:@[@"end", @{@"x": @42, @"y": @106}]]; call('EventEmitter', 'receiveTouches', [{x: 42, y: ...}])
function call(moduleName, methodName, args) { MessageQueue.init();
var module = require(moduleName); module[methodName].apply(module, args); return MessageQueue.flush(); } // EventEmitter // receiveTouches Message queue
Touch processing
What element should respond to a given event?
Button Button pressed!
Button Cancelled
Button Cancelled Scrollview
Button Scrolling stops Scrollview
Button Scrollview Horizontal Scrollview Navigator
Responder System
onStartShouldSetResponder onResponderTerminationRequest onResponderGrant onResponderMove onResponderRelease onResponderTerminate …
<TouchableOpacity> <TouchableHighlight> <TouchableBounce> <TouchableWithoutFeedback> onPress
inc() { var newCount =
this.state.count + 1; this.setState({count: newCount}); fetch( 'https://api.conunter.io/', { method: 'post', body: 'value=' + newCount } ); }
<View style={...}>
<Text style={...}> 42 </Text> <Button title="Add +1" onPress={...} /> </View> <View style={...}> <Text style={...}> 43 </Text> <Button title="Add +1" onPress={...} /> </View> 42 43
var UIManager = require('NativeModules').UIManager; UIManager.update(18, {text: '43'}); Somewhere in
React's internals:
NativeModules
NativeModules.UIManager = { ... update: function(viewID,
attributes) { MessageQueue.push( ['UIManager', 'update', [viewID, attributes]] ); } ... }; Message queue UIManager update ..
inc() { var newCount =
this.state.count + 1; this.setState({count: newCount}); fetch( 'https://api.conunter.io/', { method: 'post', body: 'value=' + newCount } ); } Message queue UIManager update .. DataManager query ....
function call(moduleName, methodName, args) { MessageQueue.init();
var module = require(moduleName); module[methodName].apply(module, args); return MessageQueue.flush(); } Message queue UIManager update .. DataManager query ....
Native Bridge JavaScript [UIManager updateView:18 props:@{@"text": @"43"}] [DataManager query:@"post" url:@"http://..."]
[ ['UIManager', 'update', [18, {text: '43'}]], ['DataManager', 'query', ['post', 'http://...']] ] Message queue UIManager update .. DataManager query ....
Native [UIManager updateView:18 props:@{@"text": @"43"}] addUIBlock:^() { UILabel *label =
viewRegistry[18]; label.text = @"43"; [label markAsDirty]; }
Layout Layout github.com/facebook/css-layout
{ margin: 20, borderBottomWidth: 2, flex: 1, alignContent: 'center', }
{ left: 120, top: 220, width: 60, height: 60, } Flexbox Coordinates
• User taps the button • Counter is updated
Native Bridge JavaScript Event (touch, timer, networks, etc.) 1 Collect
data and notify JS 2 Serialized payload 3 Process event 4 Call 0 – ∞ native methods 5 Serialized response 6 Process commands 7 Update UI (if needed) 8
Benefits
Fast
Native Bridge JavaScript Event (touch, timer, networks, etc.) 1 Update
UI (if needed) 8 Collect data and notify JS 2 Serialized payload 3 Process event 4 Call 0 – ∞ native methods 5 Serialized response 6 Process commands 7
Record / Replay
Flexible JS runtime
Native Bridge JavaScript
Native Bridge JavaScript Awesome App
Native Bridge JavaScript Awesome App WebKit process IPC
Native Bridge JavaScript Awesome App Chrome Debugger WebSockets
Live demo iPhone -> Chrome
None
None
Heroku iPhone
Streaming
None
UI = ƒ(data)
Thank you! github.com/frantic/tlv-2015 @alex_frantic