Link
Embed
Share
Beginning
This slide
Copy link URL
Copy link URL
Copy iframe embed code
Copy iframe embed code
Copy javascript embed code
Copy javascript embed code
Share
Tweet
Share
Tweet
Slide 1
Slide 1 text
Scaling React.js Applications Max Stoiber, @mxstbr Open Source Developer, Thinkmill
Slide 2
Slide 2 text
@mxstbr
Slide 3
Slide 3 text
KeystoneJS
Slide 4
Slide 4 text
ElementalUI
Slide 5
Slide 5 text
@mxstbr
Slide 6
Slide 6 text
@mxstbr
Slide 7
Slide 7 text
@mxstbr 2. Architecture 3. Performance 1. What is Scalability?
Slide 8
Slide 8 text
@mxstbr 2. Architecture 3. Performance 1. What is Scalability?
Slide 9
Slide 9 text
“[Scalability] is the capability of a system to be enlarged…” Wikipedia
Slide 10
Slide 10 text
@mxstbr 2. Architecture 3. Performance 1. What is Scalability?
Slide 11
Slide 11 text
@mxstbr Containers and Components
Slide 12
Slide 12 text
@mxstbr Structure
Slide 13
Slide 13 text
@mxstbr Traditionally grouped by type
Slide 14
Slide 14 text
@mxstbr react-app-by-type !"" css !"" actions # $"" NavBarActions.js !"" containers # $"" NavBar.js !"" constants # $"" NavBarConstants.js !"" components # $"" App.js $"" reducers $"" NavBarReducer.js
Slide 15
Slide 15 text
@mxstbr Group by feature instead
Slide 16
Slide 16 text
@mxstbr react-app-by-feature !"" css !"" containers # $"" NavBar # !"" NavBar.js # !"" actions.js # !"" constants.js # $"" reducer.js $"" components $"" App.js
Slide 17
Slide 17 text
@mxstbr Easy renaming and moving
Slide 18
Slide 18 text
@mxstbr import { toggleNav } from ‘containers/NavBar/actions.js’;
Slide 19
Slide 19 text
@mxstbr import { toggleNav } from ‘containers/PrimaryNav/actions.js’;
Slide 20
Slide 20 text
@mxstbr Work in a single folder
Slide 21
Slide 21 text
@mxstbr Reusable components
Slide 22
Slide 22 text
@mxstbr Styling??
Slide 23
Slide 23 text
@mxstbr .header { /* … */ } .title { background-color: yellow; } .footer { /* … */ } .title { border-color: blue; } Conflict! Naming
Slide 24
Slide 24 text
@mxstbr CSS Modules
Slide 25
Slide 25 text
@mxstbr import styles from ‘styles.css’; render() { return (
); }
Slide 26
Slide 26 text
@mxstbr .footer { /* … */ } .title { /* … */ } .MyApp__footer__1co1k { /* … */ } .MyApp__title__2fgr5s { /* … */ }
Slide 27
Slide 27 text
@mxstbr .header { line-height: 1.5em; } a { line-height: 1.5em; } .title { line-height: 1.5em; } Inheritance
Slide 28
Slide 28 text
@mxstbr .header { line-height: 1.5em; } .title { line-height: 1.5em; } Inheritance .footer { line-height: 1em; } .title { line-height: 1em; } Conflict!
Slide 29
Slide 29 text
@mxstbr Reset Header Title Global Reset Reset Header Local Reset Reset Title
Slide 30
Slide 30 text
@mxstbr PostCSS
Slide 31
Slide 31 text
@mxstbr PostCSS + postcss-autoreset
Slide 32
Slide 32 text
@mxstbr .header { line-height: 1.5em; } a { line-height: default; } .title { line-height: default; }
Slide 33
Slide 33 text
@mxstbr react-app-by-feature !"" containers # $"" NavBar # !"" NavBar.js # !"" actions.js # !"" constants.js # !"" styles.css # $"" reducer.js $"" components $"" App.js
Slide 34
Slide 34 text
@mxstbr Component Isolation!
Slide 35
Slide 35 text
@mxstbr Data Fetching??
Slide 36
Slide 36 text
@mxstbr redux-thunk?
Slide 37
Slide 37 text
@mxstbr function fetchData() { return (dispatch) => { dispatch(dataFetching()); fetch(‘myapi.com/‘, (data) => { dispatch(dataFetched(data)); }); } }
Slide 38
Slide 38 text
@mxstbr function fetchData() { return (dispatch) => { dispatch(dataFetching()); fetch(‘myapi.com/‘, (data) => { // TODO: Error handling dispatch(dataFetched(data)); }); } }
Slide 39
Slide 39 text
@mxstbr redux-saga
Slide 40
Slide 40 text
@mxstbr function* fetchData() { while (true) { yield take(FETCH_DATA); put(dataFetching()); const data = yield call(fetch(‘myapi.com/'); put(dataFetched(data)); } }
Slide 41
Slide 41 text
@mxstbr function* fetchData() { while (true) { yield take(FETCH_DATA); put(dataFetching()); const data = yield call(fetch(‘myapi.com/'); put(dataFetched(data)); } }
Slide 42
Slide 42 text
@mxstbr function* fetchData() { while (true) { yield take(FETCH_DATA); put(dataFetching()); const data = yield call(fetch(‘myapi.com/'); put(dataFetched(data)); } }
Slide 43
Slide 43 text
@mxstbr function* fetchData() { while (true) { yield take(FETCH_DATA); put(dataFetching()); const data = yield call(fetch(‘myapi.com/'); put(dataFetched(data)); } }
Slide 44
Slide 44 text
@mxstbr function* fetchData() { while (true) { yield take(FETCH_DATA); put(dataFetching()); const data = yield call(fetch(‘myapi.com/'); put(dataFetched(data)); } }
Slide 45
Slide 45 text
@mxstbr function* fetchData() { while (true) { yield take(FETCH_DATA); put(dataFetching()); const data = yield call(fetch(‘myapi.com/'); // TODO: Error handling put(dataFetched(data)); } }
Slide 46
Slide 46 text
@mxstbr
Slide 47
Slide 47 text
@mxstbr
Slide 48
Slide 48 text
@mxstbr
Slide 49
Slide 49 text
@mxstbr function* connectClockToTimer() { while (true) { yield take(START_BUTTON_CLICKED); put(startTimer()); yield take(STOP_BUTTON_CLICKED); put(stopTimer()); put(showTimeOnClock()); } }
Slide 50
Slide 50 text
@mxstbr function* connectClockToTimer() { while (true) { yield take(START_BUTTON_CLICKED); put(startTimer()); yield take(STOP_BUTTON_CLICKED); put(stopTimer()); put(showTimeOnClock()); } }
Slide 51
Slide 51 text
@mxstbr function* connectClockToTimer() { while (true) { yield take(START_BUTTON_CLICKED); put(startTimer()); yield take(STOP_BUTTON_CLICKED); put(stopTimer()); put(showTimeOnClock()); } }
Slide 52
Slide 52 text
@mxstbr function* connectClockToTimer() { while (true) { yield take(START_BUTTON_CLICKED); put(startTimer()); yield take(STOP_BUTTON_CLICKED); put(stopTimer()); put(showTimeOnClock()); } }
Slide 53
Slide 53 text
@mxstbr function* connectClockToTimer() { while (true) { yield take(START_BUTTON_CLICKED); put(startTimer()); yield take(STOP_BUTTON_CLICKED); put(stopTimer()); put(showTimeOnClock()); } }
Slide 54
Slide 54 text
@mxstbr Decoupled Components
Slide 55
Slide 55 text
@mxstbr 2. Group files by feature 3. Isolate Styling 1. Containers and Components 4. Use redux-saga
Slide 56
Slide 56 text
@mxstbr 2. Architecture 3. Performance 1. What is Scalability?
Slide 57
Slide 57 text
@mxstbr
Slide 58
Slide 58 text
@mxstbr
Slide 59
Slide 59 text
@mxstbr
Slide 60
Slide 60 text
@mxstbr
Slide 61
Slide 61 text
@mxstbr
Slide 62
Slide 62 text
@mxstbr shouldComponentUpdate
Slide 63
Slide 63 text
@mxstbr
Slide 64
Slide 64 text
@mxstbr class NavBar extends React.Component { shouldComponentUpdate(nextProps) { ????? } }
Slide 65
Slide 65 text
@mxstbr class NavBar extends React.Component { shouldComponentUpdate(nextProps) { return nextProps !== this.props; } }
Slide 66
Slide 66 text
@mxstbr { “username”: “@mxstbr” } { “username”: “@mxstbr” } !==
Slide 67
Slide 67 text
@mxstbr Deeply comparing objects is expensive
Slide 68
Slide 68 text
@mxstbr ImmutableJS
Slide 69
Slide 69 text
@mxstbr import { fromJS } from ‘immutable’; const state = fromJS({ “username”: “@mxstbr” });
Slide 70
Slide 70 text
@mxstbr .equals fromJS({ “username”: “@mxstbr” }) fromJS({ “username”: “@mxstbr” })
Slide 71
Slide 71 text
@mxstbr Deeply comparing objects is cheap!
Slide 72
Slide 72 text
@mxstbr
Slide 73
Slide 73 text
@mxstbr
Slide 74
Slide 74 text
@mxstbr 2. Architecture 3. Performance 1. What is Scalability?
Slide 75
Slide 75 text
Thanks for having me! Tweet comments/feedback to @mxstbr Come talk to me!