JavaScript, React Native and Performance at react-europe 2016

Post on 16-Apr-2017

1.085 views 1 download

Transcript of JavaScript, React Native and Performance at react-europe 2016

JAVASCRIPT, REACT NATIVE &Performance

@tadeuzagallo

ABOUT ME

@tadeuzagallo

React Native StartupOVERVIEW

@tadeuzagallo

@tadeuzagallo

React Native'sGOALS

@tadeuzagallo

Hybrid APPS

@tadeuzagallo

Performance Goals▸ Reduce Memory Usage▸ Reduce Startup Overhead

@tadeuzagallo

NativeOPTIMISATIONS

@tadeuzagallo

MULTI-THREADEDInitialisation

@tadeuzagallo

@tadeuzagallo

@tadeuzagallo

LAZYModule Initialisation

@tadeuzagallo

@tadeuzagallo

SmarterBATCHING

@tadeuzagallo

@tadeuzagallo

@tadeuzagallo

@tadeuzagallo

JavaScriptOPTIMISATIONS

@tadeuzagallo

INLINE/LAZYRequires

@tadeuzagallo

var alert = require('alert');

// ...

<TouchableHighlight onPress={() => alert('Touched')}> // ...</Touchable>

@tadeuzagallo

// ...

<TouchableHighlight onPress={() => require('alert')('Touched')}> // ...</Touchable>

@tadeuzagallo

DEAD CODE ELIMINATION

@tadeuzagallo

if (__DEV__) { require('DebugOnlyModule');}

const Alert = Platform.OS == 'ios' ? require('AlertIOS') : require('AlertAndroid');

@tadeuzagallo

// dev=false&minify=true

// platform=ios

const Alert = require('AlertIOS');

// platform=android

const Alert = require('AlertAndroid');

@tadeuzagallo

AND MORE...Optimise polyfills, extract babel helpers, ...

@tadeuzagallo

@tadeuzagallo

@tadeuzagallo

What next?

@tadeuzagallo

@tadeuzagallo

We shape our codeIN TERMS OF THE VM

@tadeuzagallo

@tadeuzagallo

VMARCHITECTURE

@tadeuzagallo

@tadeuzagallo

@tadeuzagallo

@tadeuzagallo

@tadeuzagallo

@tadeuzagallo

But on iOS...

@tadeuzagallo

@tadeuzagallo

@tadeuzagallo

TL;DRTHIRD-PARTY APPS CAN'T JIT ON iOS

@tadeuzagallo

@tadeuzagallo

WHAT ABOUTAndroid?

@tadeuzagallo

WE CAN JIT ON Android!

@tadeuzagallo

...BUT IT'S SLOWER*...

@tadeuzagallo

ANDROID SETUP

@tadeuzagallo

Profile, profile and profile

@tadeuzagallo

@tadeuzagallo

Parsing isEXPENSIVE

@tadeuzagallo

@tadeuzagallo

var hello = "Hello, World!";

var HelloWorld = function() { return React.createElement('div', null, hello);};

ReactDOM.render( React.createElement(HelloWorld), document.body);

@tadeuzagallo

/* */ var hello = "Hello, World!";/* *//* */ var HelloWorld = function() {/* */ return React.createElement('div', null, hello);/* */ };/* *//* */ ReactDOM.render(/* */ React.createElement(HelloWorld),/* */ document.body);

@tadeuzagallo

/* ==> */ var hello = "Hello, World!";/* *//* */ var HelloWorld = function() {/* */ return React.createElement('div', null, hello);/* */ };/* *//* */ ReactDOM.render(/* */ React.createElement(HelloWorld),/* */ document.body);

@tadeuzagallo

/* */ var hello = "Hello, World!";/* *//* ==> */ var HelloWorld = function() {/* */ return React.createElement('div', null, hello);/* */ };/* *//* */ ReactDOM.render(/* */ React.createElement(HelloWorld),/* */ document.body);

@tadeuzagallo

/* */ var hello = "Hello, World!";/* *//* */ var HelloWorld = function() {/* ==> */ return React.createElement('div', null, hello);/* */ };/* *//* */ ReactDOM.render(/* */ React.createElement(HelloWorld),/* */ document.body);

@tadeuzagallo

/* */ var hello = "Hello, World!";/* *//* */ var HelloWorld = function() {/* */ return React.createElement('div', null, hello);/* */ };/* *//* ==> */ ReactDOM.render(/* */ React.createElement(HelloWorld),/* */ document.body);

@tadeuzagallo

/* */ var hello = "Hello, World!";/* *//* */ var HelloWorld = function() {/* ==> */ return React.createElement('div', null, hello);/* */ };/* *//* */ ReactDOM.render(/* */ React.createElement(HelloWorld),/* */ document.body);

@tadeuzagallo

Pre-parseCACHE

@tadeuzagallo

@tadeuzagallo

@tadeuzagallo

@tadeuzagallo

BytecodeCACHE

@tadeuzagallo

@tadeuzagallo

@tadeuzagallo

@tadeuzagallo

@tadeuzagallo

@tadeuzagallo

@tadeuzagallo

Random Access Bundle

@tadeuzagallo

import React, { Component } from 'react';import { Text, AppRegistry } from 'react-native';

var HelloWorld = () => ( <Text>Hello, World!</Text>);

AppRegistry.registerComponent('SampleApp', () => HelloWorld);

@tadeuzagallo

__d('ReactComponent', function (global, require, module, exports) { /* ... */ });__d('react', function (global, require, module, exports) { /* ... */ });__d('AppRegistry', function (global, require, module, exports) { /* ... */ });__d('Text', function (global, require, module, exports) { /* ... */ });__d('react-native', function (global, require, module, exports) { /* ... */ });__d('SampleApp.js', function (global, require, module, exports) { /* ... */ });

@tadeuzagallo

__d(0, function (global, require, module, exports) { /* ... */ });__d(1, function (global, require, module, exports) { /* ... */ });__d(2, function (global, require, module, exports) { /* ... */ });__d(3, function (global, require, module, exports) { /* ... */ });__d(4, function (global, require, module, exports) { /* ... */ });__d(5, function (global, require, module, exports) { /* ... */ });

@tadeuzagallo

{ 0: { offset: 139, size: 202 }, 1: { offset: 342, size: 255 }, 2: { offset: 598, size: 115 }, 3: { offset: 714, size: 107 }, 4: { offset: 827, size: 131 }, 5: { offset: 959, size: 382 }}/* global code */\0__d(0, function (global, require, module, exports) { /* ... */ });\0__d(1, function (global, require, module, exports) { /* ... */ });\0__d(2, function (global, require, module, exports) { /* ... */ });\0__d(3, function (global, require, module, exports) { /* ... */ });\0__d(4, function (global, require, module, exports) { /* ... */ });\0__d(5, function (global, require, module, exports) { /* ... */ });\0

@tadeuzagallo

// JavaScriptfunction require(module) { if (cached[module]) { return cached[module]; }

if (!factories[module]) { nativeRequire(module); }

cached[module] = factories[module]();}

// Nativevoid nativeRequire(module) { evaluate(RandomAccessBundle + offsets[module]);}

@tadeuzagallo

react-native bundle --entry-file index.ios.js ...

@tadeuzagallo

react-native unbundle --entry-file index.ios.js ...

@tadeuzagallo

Thank you!

@tadeuzagallo