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
770
React Native Tutorial - NYC'15
frantic
5
1.3k
Other Decks in Programming
See All in Programming
スタートアップの急成長に寄り添うOn-Call体制構築とその変遷
horimislime
3
1.1k
What We Can Do with Kubernetes Custom Controllers
zespre
1
150
【DevelopersIO 2024】AI 半可通なのにエッジ AI 機能を全力で解説してみる 〜Cloudflare の場合〜
maroon1st
0
120
Flutter gRPC - 박제창 @I/O Extended 2024 인천/송도
itsmedreamwalker
0
130
12年前の『型システム入門』翻訳の思い出話
mame
11
1.4k
JEPs の変遷から眺める Vector API / Tracking the Progress of Vector API via JEPs
mackey0225
1
120
詳解 AWS Lambdaコールドスタート
iwatatomoya
0
1.1k
GraphQL はいいぞ! ~Laravel で学ぶ GraphQL 入門~
azuki
1
190
Strip Types と Storage
yosuke_furukawa
PRO
3
240
部分型について探ってみよう
pd1xx
2
120
マケデコ プログラミングに頼らないExcelシートと生成AIによる日本株データ分析 発表資料
gamella
1
310
Next.jsをフルスタックフレームワークとして使ってみた
mongolyy
1
100
Featured
See All Featured
Rebuilding a faster, lazier Slack
samanthasiow
78
8.5k
Designing Experiences People Love
moore
137
23k
Designing the Hi-DPI Web
ddemaree
277
34k
No one is an island. Learnings from fostering a developers community.
thoeni
18
2.8k
Optimizing for Happiness
mojombo
373
69k
Java REST API Framework Comparison - PWX 2021
mraible
PRO
26
7.2k
How STYLIGHT went responsive
nonsquared
93
5k
Web development in the modern age
philhawksworth
203
10k
Large-scale JavaScript Application Architecture
addyosmani
507
110k
The Art of Programming - Codeland 2020
erikaheidi
48
13k
Adopting Sorbet at Scale
ufuk
71
8.8k
Music & Morning Musume
bryan
43
5.9k
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