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
420
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
320
Styling Intro
mxstbr
3
380
Introduction to React.js
mxstbr
1
150
Styling React Applications
mxstbr
2
660
Scaling React.js Applications
mxstbr
0
410
Offline is the new Black
mxstbr
3
1.1k
Exploring ES6
mxstbr
1
320
Testing React.js Applications
mxstbr
4
650
Other Decks in Technology
See All in Technology
研究開発部メンバーの働き⽅ / Sansan R&D Profile
sansan33
PRO
3
20k
Escaping_the_Kraken_-_October_2025.pdf
mdalmijn
0
160
LLM時代にデータエンジニアの役割はどう変わるか?
ikkimiyazaki
6
1.2k
Where will it converge?
ibknadedeji
0
200
職種別ミートアップで社内から盛り上げる アウトプット文化の醸成と関係強化/ #DevRelKaigi
nishiuma
2
160
AIAgentの限界を超え、 現場を動かすWorkflowAgentの設計と実践
miyatakoji
1
160
Oracle Base Database Service 技術詳細
oracle4engineer
PRO
11
78k
SREとソフトウェア開発者の合同チームはどのようにS3のコストを削減したか?
muziyoshiz
1
210
Reflections of AI: A Trilogy in Four Parts (GOTO; Copenhagen 2025)
ondfisk
0
110
10年の共創が示す、これからの開発者と企業の関係 ~ Crossroad
soracom
PRO
1
690
AWS Top Engineer、浮いてませんか? / As an AWS Top Engineer, Are You Out of Place?
yuj1osm
2
200
Optuna DashboardにおけるPLaMo2連携機能の紹介 / PFN LLM セミナー
pfn
PRO
2
940
Featured
See All Featured
Designing Experiences People Love
moore
142
24k
Why Our Code Smells
bkeepers
PRO
339
57k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
127
53k
Easily Structure & Communicate Ideas using Wireframe
afnizarnur
194
16k
We Have a Design System, Now What?
morganepeng
53
7.8k
Connecting the Dots Between Site Speed, User Experience & Your Business [WebExpo 2025]
tammyeverts
9
590
Building an army of robots
kneath
306
46k
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
657
61k
Six Lessons from altMBA
skipperchong
28
4k
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
162
15k
Navigating Team Friction
lara
189
15k
The Straight Up "How To Draw Better" Workshop
denniskardys
237
140k
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!