Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
React Native: Under the Hood
Search
Alexander Kotliarskyi
June 09, 2015
Programming
22k
31
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
React Native: Under the Hood
Alexander Kotliarskyi
June 09, 2015
More Decks by Alexander Kotliarskyi
See All by Alexander Kotliarskyi
Building Stellar User Experiences with React Native
frantic
2
1.1k
React Native Tutorial - NYC'15
frantic
5
1.5k
Other Decks in Programming
See All in Programming
まずはコードより業務と向き合う:テーブル解体のためにPdMを呼んだ話
sakawe_ee
0
180
AIがコードを書いてくれる時代、我々は何を確かめるのか
yosuke_furukawa
PRO
13
5.8k
3回つくってわかった、 定期実行ジョブ基盤の本質情報
takai
4
3.7k
FactoryBotをやめればRSpecは速くなるのか?
yuta_onishi_97
0
1.6k
Railsバージョンを4倍にした話
optim
0
950
[JA] Domain Modeling with Vanilla Rails: 「操作」から再考するRailsの設計論
yasaichi
4
1.8k
Spec-driven Development with AI
simas
PRO
0
2.3k
現場と育てるRailsモデリング 〜Spreadsheetから始めたモデル設計〜
siroemk
2
1.2k
AI駆動開発4年目の現在地(『あなたはFDEになるべきか?』イベント資料)
kumaiu
0
260
PumaからFalconに移行したRailsアプリケーションでの実践
falcon8823
0
360
作って学ぶSpring BootのAuto Configuration / JJUG Night Seminar 2026-10-19
rshindo
0
220
学びを記事・スライド・Xへ高速展開する― AI-assisted Learning Loopで回すコンテンツ生成術
ochtum
0
200
Featured
See All Featured
How Software Deployment tools have changed in the past 20 years
geshan
3
35k
Leading Effective Engineering Teams in the AI Era
addyosmani
9
2.8k
Build The Right Thing And Hit Your Dates
maggiecrowley
39
3.5k
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
287
14k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
35
2.6k
Tips & Tricks on How to Get Your First Job In Tech
honzajavorek
1
830
Unsuck your backbone
ammeep
672
58k
Imperfection Machines: The Place of Print at Facebook
scottboms
270
14k
Google's AI Overviews - The New Search
badams
0
1.7k
How To Stay Up To Date on Web Technology
chriscoyier
790
250k
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
254
23k
GraphQLの誤解/rethinking-graphql
sonatard
75
12k
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