voxxed days thesaloniki 2016 - scaling react.js applications

73
Scaling React.js Applications Max Stoiber, @mxstbr Open Source Developer, Thinkmill

Upload: voxxed-days-thessaloniki

Post on 16-Apr-2017

61 views

Category:

Software


0 download

TRANSCRIPT

Scaling React.js ApplicationsMax Stoiber, @mxstbrOpen Source Developer, Thinkmill

@mxstbr

KeystoneJS

ElementalUI

@mxstbr

@mxstbr

@mxstbr

2. State Management3. Architecture

1. What is Scalability?

4. Performance

@mxstbr

2. State Management3. Architecture

1. What is Scalability?

4. Performance

@mxstbr

2. State Management3. Architecture

1. What is Scalability?

4. Performance

@mxstbr

@mxstbr

@mxstbr

@mxstbr

Unidirectional Data Flow

@mxstbr

Store

@mxstbr

@mxstbr

2. State Management3. Architecture

1. What is Scalability?

4. Performance

@mxstbr

Containers and Components

@mxstbr

Structure

@mxstbr

Traditionally grouped by type

@mxstbr

react-app-by-type!"" css!"" actions#   $"" NavBarActions.js!"" containers#   $"" NavBar.js!"" constants#   $"" NavBarConstants.js!"" components#   $"" App.js$"" reducers $"" NavBarReducer.js

@mxstbr

Group by feature instead

@mxstbr

react-app-by-feature!"" css!"" containers#   $"" NavBar#   !"" NavBar.js#   !"" actions.js#   !"" constants.js#   $"" reducer.js$"" components $"" App.js

@mxstbr

Easy renaming and moving

@mxstbr

import { toggleNav } from ‘containers/NavBar/actions.js’;

@mxstbr

import { toggleNav } from ‘containers/PrimaryNav/actions.js’;

@mxstbr

Work in a single folder

@mxstbr

Reusable components

@mxstbr

Styling??

@mxstbr

.header {

/* … */

}

.title {

background-color: yellow;

}

.footer {

/* … */

}

.title {

border-color: blue;

}

Conflict!

Naming

@mxstbr

CSS Modules

@mxstbr

import styles from ‘styles.css’;

render() {

return (

<div

className={styles.footer}

/>

);

}

@mxstbr

.footer { /* … */ }

.title { /* … */ }

.MyApp__footer__1co1k { /* … */ }

.MyApp__title__2fgr5s { /* … */ }

@mxstbr

.header { line-height: 1.5em; }

a { line-height: 1.5em; }

.title { line-height: 1.5em; }

Inheritance

@mxstbr

.header { line-height: 1.5em;}

.title { line-height: 1.5em;}

Inheritance.footer { line-height: 1em;}

.title { line-height: 1em;}

Conflict!

@mxstbr

Reset

Header

Title

Global Reset

Reset

Header

Local Reset

Reset

Title

@mxstbr

PostCSS

@mxstbr

PostCSS+

postcss-autoreset

@mxstbr

.header { line-height: 1.5em; }

a { line-height: default; }

.title { line-height: default; }

@mxstbr

react-app-by-feature!"" containers#   $"" NavBar#   !"" NavBar.js#   !"" actions.js#   !"" constants.js#   !"" styles.css#   $"" reducer.js$"" components $"" App.js

@mxstbr

Component Isolation!

@mxstbr

Data Fetching??

@mxstbr

<Clock /> <Timer />

@mxstbr

<Clock onStartClick={ dipatch(startTimer()) }/>

<Timer onStopClick={ dispatch(showTime()) }/>

@mxstbr

redux-saga

@mxstbr

<Clock onStartClick={ dipatch(startClicked()) }/>

<Timer onStopClick={ dispatch(stopClicked()) }/>

@mxstbr

function* connectClockToTimer() { while (true) { yield take(START_BUTTON_CLICKED); put(startTimer()); yield take(STOP_BUTTON_CLICKED); put(stopTimer()); put(showTimeOnClock()); }}

@mxstbr

function* connectClockToTimer() { while (true) { yield take(START_BUTTON_CLICKED); put(startTimer()); yield take(STOP_BUTTON_CLICKED); put(stopTimer()); put(showTimeOnClock()); }}

@mxstbr

function* connectClockToTimer() { while (true) { yield take(START_BUTTON_CLICKED); put(startTimer()); yield take(STOP_BUTTON_CLICKED); put(stopTimer()); put(showTimeOnClock()); }}

@mxstbr

function* connectClockToTimer() { while (true) { yield take(START_BUTTON_CLICKED); put(startTimer()); yield take(STOP_BUTTON_CLICKED); put(stopTimer()); put(showTimeOnClock()); }}

@mxstbr

function* connectClockToTimer() { while (true) { yield take(START_BUTTON_CLICKED); put(startTimer()); yield take(STOP_BUTTON_CLICKED); put(stopTimer()); put(showTimeOnClock()); }}

@mxstbr

Decoupled Components

@mxstbr

2. Group files by feature3. Isolate Styling

1. Containers and Components

4. Use redux-saga

@mxstbr

2. State Management3. Architecture

1. What is Scalability?

4. Performance

@mxstbr

WebpackCode Splitting

@mxstbr

@mxstbr

@mxstbr

@mxstbr

@mxstbr

@mxstbr

shouldComponentUpdate

@mxstbr

@mxstbr

class NavBar extends React.Component { shouldComponentUpdate(nextProps) { ????? }}

@mxstbr

class NavBar extends React.Component { shouldComponentUpdate(nextProps) { return nextProps !== this.props; }}

@mxstbr

{ “username”: “@mxstbr” } { “username”: “@mxstbr” }!==

@mxstbr

Deeply comparing objectsis expensive

@mxstbr

ImmutableJS

@mxstbr

import { fromJS } from ‘immutable’;

const state = fromJS({ “username”: “@mxstbr”});

@mxstbr

.equals

fromJS({ “username”: “@mxstbr” })

fromJS({ “username”: “@mxstbr” })

@mxstbr

Deeply comparing objectsis cheap!

@mxstbr

@mxstbr

@mxstbr

2. State Management3. Architecture

1. What is Scalability?

4. Performance

Thanks for having me!Tweet comments/feedback to @mxstbrCome talk to me!