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
940
React Native Tutorial - NYC'15
frantic
5
1.4k
Other Decks in Programming
See All in Programming
Workers を定期実行する方法は一つじゃない
rokuosan
0
140
Android 15以上でPDFのテキスト検索を爆速開発!
tonionagauzzi
0
180
GUI操作LLMの最新動向: UI-TARSと関連論文紹介
kfujikawa
0
180
Terraform やるなら公式スタイルガイドを読もう 〜重要項目 10選〜
hiyanger
11
2.8k
バイブスあるコーディングで ~PHP~ 便利ツールをつくるプラクティス
uzulla
1
320
新世界の理解
koriym
0
130
リバースエンジニアリング新時代へ! GhidraとClaude DesktopをMCPで繋ぐ/findy202507
tkmru
7
1.7k
Claude Code と OpenAI o3 で メタデータ情報を作る
laket
0
110
構文解析器入門
ydah
7
2k
[SRE NEXT] 複雑なシステムにおけるUser Journey SLOの導入
yakenji
1
900
CLI ツールを Go ライブラリ として再実装する理由 / Why reimplement a CLI tool as a Go library
ktr_0731
3
940
Flutterと Vibe Coding で個人開発!
hyshu
1
210
Featured
See All Featured
Embracing the Ebb and Flow
colly
86
4.8k
Building a Modern Day E-commerce SEO Strategy
aleyda
43
7.4k
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
18
1k
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
34
3.1k
How STYLIGHT went responsive
nonsquared
100
5.7k
Why You Should Never Use an ORM
jnunemaker
PRO
58
9.5k
The Cult of Friendly URLs
andyhume
79
6.5k
4 Signs Your Business is Dying
shpigford
184
22k
Building Adaptive Systems
keathley
43
2.7k
A designer walks into a library…
pauljervisheath
207
24k
Understanding Cognitive Biases in Performance Measurement
bluesmoon
29
1.8k
Optimising Largest Contentful Paint
csswizardry
37
3.4k
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