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
410
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
630
Scaling React.js Applications
mxstbr
0
410
Offline is the new Black
mxstbr
3
1k
Exploring ES6
mxstbr
1
320
Testing React.js Applications
mxstbr
4
630
Other Decks in Technology
See All in Technology
AI時代にも変わらぬ価値を発揮したい: インフラ・クラウドを切り口にユーザー価値と非機能要件に向き合ってエンジニアとしての地力を培う
netmarkjp
0
200
自分がLinc’wellで提供しているプロダクトを理解するためにやったこと
murabayashi
1
140
三視点LLMによる複数観点レビュー
mhlyc
0
260
LLM拡張解体新書/llm-extension-deep-dive
oracle4engineer
PRO
27
7.7k
PHPからはじめるコンピュータアーキテクチャ / From Scripts to Silicon: A Journey Through the Layers of Computing
tomzoh
2
360
今日からあなたもGeminiを好きになる
subaruhello
1
430
複数のGemini CLIが同時開発する狂気 - Jujutsuが実現するAIエージェント協調の新世界
gunta
7
1.7k
Step Functions First - サーバーレスアーキテクチャの新しいパラダイム
taikis
1
230
AIコードアシスタントとiOS開発
jollyjoester
1
220
データ戦略部門 紹介資料
sansan33
PRO
1
3.3k
「現場で活躍するAIエージェント」を実現するチームと開発プロセス
tkikuchi1002
5
900
激動の時代、新卒エンジニアはAIツールにどう向き合うか。 [LayerX Bet AI Day Countdown LT Day1 ツールの選択]
tak848
0
110
Featured
See All Featured
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
32
2.4k
A Tale of Four Properties
chriscoyier
160
23k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
31
1.3k
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
44
2.4k
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
507
140k
Why Our Code Smells
bkeepers
PRO
337
57k
Code Review Best Practice
trishagee
69
19k
Why You Should Never Use an ORM
jnunemaker
PRO
58
9.5k
Fantastic passwords and where to find them - at NoRuKo
philnash
51
3.3k
How to train your dragon (web standard)
notwaldorf
96
6.1k
Build your cross-platform service in a week with App Engine
jlugia
231
18k
RailsConf 2023
tenderlove
30
1.2k
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!