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
Scaling React.js Applications (short version)
Search
Max Stoiber
September 16, 2016
Technology
2
390
Scaling React.js Applications (short version)
25 minute super-speed introduction to scaling react applications!
Max Stoiber
September 16, 2016
Tweet
Share
More Decks by Max Stoiber
See All by Max Stoiber
Testing React Applications
mxstbr
3
310
Styling Intro
mxstbr
3
370
Introduction to React.js
mxstbr
1
140
Styling React Applications
mxstbr
2
590
Scaling React.js Applications
mxstbr
0
390
Offline is the new Black
mxstbr
3
990
Exploring ES6
mxstbr
1
310
Testing React.js Applications
mxstbr
4
580
Other Decks in Technology
See All in Technology
Developer Summit 2025 [14-D-1] Yuki Hattori
yuhattor
19
5.1k
スクラムのイテレーションを導入してチームの雰囲気がより良くなった話
eccyun
0
110
開発者が自律的に AWS Security Hub findings に 対応する仕組みと AWS re:Invent 2024 登壇体験談 / Developers autonomously report AWS Security Hub findings Corresponding mechanism and AWS re:Invent 2024 presentation experience
kaminashi
0
190
君も受託系GISエンジニアにならないか
sudataka
2
370
AndroidXR 開発ツールごとの できることできないこと
donabe3
0
110
マルチモーダル理解と生成の統合 DeepSeek Janus, etc... / Multimodal Understanding and Generation Integration
hiroga
0
360
AndroidデバイスにFTPサーバを建立する
e10dokup
0
240
アジャイル開発とスクラム
araihara
0
160
ビジネスと現場活動をつなぐソフトウェアエンジニアリング~とあるスタートアッププロダクトの成長記録より~
mizunori
0
210
技術的負債解消の取り組みと専門チームのお話 #技術的負債_Findy
bengo4com
1
1.2k
APIファーストで実現する運用性の高い IoT プラットフォーム: SORACOMのアプローチ
soracom
PRO
0
240
転生CISOサバイバル・ガイド / CISO Career Transition Survival Guide
kanny
3
410
Featured
See All Featured
Why You Should Never Use an ORM
jnunemaker
PRO
55
9.2k
Thoughts on Productivity
jonyablonski
69
4.5k
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
29
2.2k
A designer walks into a library…
pauljervisheath
205
24k
Fantastic passwords and where to find them - at NoRuKo
philnash
51
3k
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
45
2.3k
Making Projects Easy
brettharned
116
6k
Fontdeck: Realign not Redesign
paulrobertlloyd
82
5.4k
Documentation Writing (for coders)
carmenintech
67
4.6k
jQuery: Nuts, Bolts and Bling
dougneiner
63
7.6k
Imperfection Machines: The Place of Print at Facebook
scottboms
267
13k
Gamification - CAS2011
davidbonilla
80
5.1k
Transcript
Scaling React.js Applications Max Stoiber, @mxstbr Open Source Developer, Thinkmill
@mxstbr
KeystoneJS
ElementalUI
@mxstbr
@mxstbr
@mxstbr 2. Architecture 3. Performance 1. What is Scalability?
@mxstbr 2. Architecture 3. Performance 1. What is Scalability?
“[Scalability] is the capability of a system to be enlarged…”
Wikipedia
@mxstbr 2. Architecture 3. Performance 1. What is Scalability?
@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 redux-thunk?
@mxstbr function fetchData() { return (dispatch) => { dispatch(dataFetching()); fetch(‘myapi.com/‘,
(data) => { dispatch(dataFetched(data)); }); } }
@mxstbr function fetchData() { return (dispatch) => { dispatch(dataFetching()); fetch(‘myapi.com/‘,
(data) => { // TODO: Error handling dispatch(dataFetched(data)); }); } }
@mxstbr redux-saga
@mxstbr function* fetchData() { while (true) { yield take(FETCH_DATA); put(dataFetching());
const data = yield call(fetch(‘myapi.com/'); put(dataFetched(data)); } }
@mxstbr function* fetchData() { while (true) { yield take(FETCH_DATA); put(dataFetching());
const data = yield call(fetch(‘myapi.com/'); put(dataFetched(data)); } }
@mxstbr function* fetchData() { while (true) { yield take(FETCH_DATA); put(dataFetching());
const data = yield call(fetch(‘myapi.com/'); put(dataFetched(data)); } }
@mxstbr function* fetchData() { while (true) { yield take(FETCH_DATA); put(dataFetching());
const data = yield call(fetch(‘myapi.com/'); put(dataFetched(data)); } }
@mxstbr function* fetchData() { while (true) { yield take(FETCH_DATA); put(dataFetching());
const data = yield call(fetch(‘myapi.com/'); put(dataFetched(data)); } }
@mxstbr function* fetchData() { while (true) { yield take(FETCH_DATA); put(dataFetching());
const data = yield call(fetch(‘myapi.com/'); // TODO: Error handling put(dataFetched(data)); } }
@mxstbr <Clock /> <Timer />
@mxstbr <Clock onStartClick={ dipatch(startTimer()) } /> <Timer onStopClick={ dispatch(showTime()) }
/>
@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 feature 3. Isolate Styling 1.
Containers and Components 4. Use redux-saga
@mxstbr 2. Architecture 3. Performance 1. What is Scalability?
@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 objects is expensive
@mxstbr ImmutableJS
@mxstbr import { fromJS } from ‘immutable’; const state =
fromJS({ “username”: “@mxstbr” });
@mxstbr .equals fromJS({ “username”: “@mxstbr” }) fromJS({ “username”: “@mxstbr” })
@mxstbr Deeply comparing objects is cheap!
@mxstbr
@mxstbr
@mxstbr 2. Architecture 3. Performance 1. What is Scalability?
Thanks for having me! Tweet comments/feedback to @mxstbr Come talk
to me!