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
Ready for Async Rendering
Search
koba04
April 19, 2018
Programming
6
1.4k
Ready for Async Rendering
Scramble! #1 Frontend
https://folio.connpass.com/event/82816/
koba04
April 19, 2018
Tweet
Share
More Decks by koba04
See All by koba04
Standing on the shoulders of giants
koba04
0
2.5k
React/Next によるアプリケーション開発のこれから
koba04
60
16k
フロントエンド刷新をプロジェクトとして進める際に気をつけていること
koba04
3
1.7k
How useEvent would change our applications
koba04
1
2.8k
kintoneフロントエンド刷新によるモノリスからの脱却とその先に目指す未来
koba04
3
14k
Make it Declarative with React
koba04
0
1.3k
Ready for React in 2019
koba04
2
1.6k
Algorithms in React
koba04
13
11k
Suspense and TimeSlicing
koba04
0
230
Other Decks in Programming
See All in Programming
AppRouter Panel Talk
yosuke_furukawa
PRO
1
520
一文字エイリアスのすすめ
fujimura
0
190
WebGLで始める コンピュータグラフィックス入門
heller77
0
370
Jetpack Composeとデザインシステム
rmakiyama
0
230
酒飲んでたらテックリードになった話
spbaya0141
0
210
RustでAWS Lambda functionをいい感じに書く
taiki45
2
150
Balkan Ruby 2024 — How and why to run SQLite on Rails in production
fractaledmind
0
110
Effectで作る堅牢でスケーラブルなAPIゲートウェイ / Robust and Scalable API Gateway Built on Effect
yasaichi
7
1.2k
TypeScriptから始める VR生活
tamagokakeg
2
110
Criando a Woovi em uma semana
daniloab
0
120
最近コードレビューで指摘したこと
forrep
3
110
ペパボOpenTelemetry革命
pyama86
2
780
Featured
See All Featured
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
123
39k
Music & Morning Musume
bryan
41
5.6k
Imperfection Machines: The Place of Print at Facebook
scottboms
261
12k
What the flash - Photography Introduction
edds
64
11k
Debugging Ruby Performance
tmm1
70
11k
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
352
28k
Writing Fast Ruby
sferik
622
60k
Become a Pro
speakerdeck
PRO
13
4.6k
ReactJS: Keep Simple. Everything can be a component!
pedronauck
660
120k
Why Our Code Smells
bkeepers
PRO
331
56k
Making Projects Easy
brettharned
109
5.5k
Reflections from 52 weeks, 52 projects
jeffersonlam
345
19k
Transcript
3FBEZGPS"TZOD3FOEFSJOH 4DSBNCMF !LPCB
None
"HFOEB w 8IBUJT"TZOD3FOEFSJOH w -JGFDZDMF.FUIPET4USJDU.PEF w 5JNF4MJDJOH w 3FBDU4VTQFOTF
w "QQFOEJY v16.3 Changes
8IBUJT"TZOD3FOEFSJOH
w 3FBDU'JCFSJTBOVOJUPGXPSL 㲈3FBDU&MFNFOU w *UJTQPTTJCMFUPTUPQBOESFTVNFVQEBUFT 3FDBQ3FBDU'JCFS FiberA FiberB FiberD
FiberE Commit all SideEffects Idle Time Idle Time Idle Time SideEffect SideEffect Host (DOM) FiberC Render Phase Commit Phase
w 3FOEFS1IBTFʜ"TZOD w $PNNJU1IBTFʜ4ZOD 3FDBQ3FBDU'JCFS FiberA FiberB FiberD FiberE Commit
all SideEffects Idle Time Idle Time Idle Time SideEffect SideEffect Host (DOM) FiberC Async Sync
4VTQFOEBOE3FTVNF FiberA FiberB FiberA FiberC Commit Low Priority Sync Priority
Commit FiberA FiberB FiberC Low Priority Reuse Interrupt Suspend
-JGFDZDMF.FUIPET
$IBOHFTGPSMJGFDZDMFNFUIPET http://blog.koba04.com/post/2018/04/04/react-v163-changes/
w $BMMFEBU3FOEFS1IBTF w 3FUVSOBQBSUJBMTUBUFCBTFEPOOFYU1SPQT w TUBUJDHFU%FSJWFE4UBUF'SPN1SPQT static getDerivedStateFromProps(nextProps, prevState) {
if (nextProps.category !== prevState.category) { return { data: null, category: null }; } return null; } componentDidUpdate() { if (this.state.category == null) { fetchData(this.props.category).then((data) => { this.setState({category: this.props.category, data}); }); }
w $BMMFEBU$PNNJU1IBTF w 3FUVSOBTOBQTIPU BOZ CFGPSFVQEBUFUIF)PTU w UIFTOBQTIPUJTQBTTFEUPDPNQPOFOU%JE6QEBUF HFU4OBQTIPU#FGPSF6QEBUF getSnapshotBeforeUpdate()
{ return { scrollHeight: document.body.scrollHeight, scrollTop: document.body.scrollTop, }; } componentDidUpdate(prevProps, prevState, snapshot) { const {body} = document; const {scrollTop, scrollHeight} = snapshot; body.scrollTop = scrollTop + (body.scrollHeight - scrollHeight); }
https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html#examples
https://github.com/facebook/react/tree/master/packages/create-subscription
4USJDU.PEF
w *EFOUJGZJOHDPNQPOFOUTVOTBGFMJGFDZDMFT w 8BSOJOHBCPVUMFHBDZTUSJOHSFG"1*VTBHF w %FUFDUJOHVOFYQFDUFETJEFF⒎FDUT 4USJDU.PEF const {StrictMode} =
React; const App = () => ( <StrictMode> <Header /> <Main /> <Footer /> </StrictMode> );
/FX$BQBCJMJUJFT
https://reactjs.org/blog/2018/03/01/sneak-peek-beyond-react-16.html
5JNF4MJDJOH
w #MPDLJOH6*UISFBEJTBOBXGVMFYQFSJFODF w 5IFSFBSFNBOZQFPQMFXIPVTFMPXQPXFSEFWJDFT w 8IZOPUEFCPVODFPSUISPUUMF 5IFBOTXFSJTʜ w SFRVFTU*EMF$BMMCBDL 5JNF4MJDJOH
<AsyncMode> <FilterInput onChange={value => { ReactDOM.flushSync(() => this.setState({value})); this.setState({data: this.filterData(value)}); }} /> </AsyncMode>
https://koba04.github.io/react-fiber-resources/examples/ Async Update Sync Update
None
https://zeit.co/blog/domains-search-web
3FBDU4VTQFOTF
https://github.com/facebook/react/pull/12279
w 3FBDU4VTQFOTFJTBGFBUVSFUPIBOEMFBTZODVQEBUFT w )5513FRVFTU w %ZOBNJD-PBEJOH w )BOEMJOHBTZODISPOPVTVQEBUFTBSFTPIBSEʜ w 4UBSU-PBEJOH
"1*4VDDFTT &SSPSʜ w .BOZMPBEJOHTQJOOFST KBOLCZBGBTUSFTQPOTF 3FBDU4VTQFOTF
3FBDU4VTQFOTF "1*XJMMCFDIBOHFE import SimpleCacheProvider from ‘simple-cache-provider’; const cache = SimpleCacheProvider.createCache();
const userFetcher = id => SimpleCacheProvider.createResource(id => fetch(`/api/users/${id}`).then(res => res.json()); )(cache, id); const User = props => { const user = userFetcher.read(props.id); return <div>{user.name}</div>; }; const Fallback = props => ( <React.Timeout ms={props.timeout}> {didExpire => didExpire ? props.placeholder : props.children} </React.Timeout> ); <Fallback placeholder=“Loading…” timeout={200}> <User id={100} /> </Fallback>
3FBDU4VTQFOTF "1*XJMMCFDIBOHFE import SimpleCacheProvider from ‘simple-cache-provider’; const cache = SimpleCacheProvider.createCache();
const routeFetcher = Component => SimpleCacheProvider.createResource(Component => import(Component).then(module => module.default); )(cache, Component); const UserPage = () => { const Component = routeFetcher.read(‘./pages/User’); return <Component />; }; const Fallback = props => ( <React.Timeout ms={props.timeout}> {didExpire => didExpire ? props.placeholder : props.children} </React.Timeout> ); <Fallback placeholder=“Loading…” timeout={1000}> <UserPage /> </Fallback>
Empty Pending Resolved Rejected read or preload throw promise return
value from cache Cache load
w 3FBDU4VTQFOTFJTCBTFEPO&SSPS#PVOEBSJFT UIPVHI XIJDIUISPXT1SPNJTFJOTUFBEPG&SSPS )PXEPFT3FBDU4VTQFOTFXPSL User Fallback Timeout throw Promise!
(suspend) timeout render with fetched Data (resume)
https://github.com/facebook/react/pull/12201
w 5IF"1*JTOPUpOBM"1* NJHIUCFDIBOHFE w *IFBSESFOEFSGVODUJPONVTUOPUIBWFBOZTJEFF⒎FDUT w 3FBDU4VTQFOTFPO443SFOEFSFS w
1SFSFOEFSBOEQSFMPBEJOHXJUIIJEEFOQSPQT w "XFTPNF8IFODBO*VTF3FBDU4VTQFOTF w .BZCFJOʜ 3FBDU4VTQFOTF
"QQFOEJY
/FX$POUFYU"1* const LangContext = React.createContext(‘en’); const ThemeContext = React.createContext(‘dark’); const
App = () => ( <LangContext.Provider value=“en”> <ThemeContext.Provider value=“dark”> <Child> <LangContext.Consumer> {lang => ( <ThemeContext.Consumer> {theme => ( <button className={theme}> {getMessage(‘click’, lang)} </button> )} </ThemeContext.Consumer> )} </LangContext.Consumer> </Child> </ThemeContext.Provider> </LangContext.Provider> );
w )BSEUPUZQFDIFDLJOH w TIPVME$PNQPOFOU6QEBUFNJHIUCSFBLUIFVQEBUF 1SPCMFNTPGMFHBDZ$POUFYU"1* GrandChild Child Parent ThemeContext Brown
-> Orange shouldComponentUpdate return false;
w 0QUJNJ[FUIFVQEBUFTGPS$POUFYUWBMVF w 3FBDUVTFTCJUXJTFPQFSBUPSJUTJOUFSOBMT 0CTFSWFE#JUT VOTUBCMF⚠ const StoreContext = React.createContext(null,
(prev, next) => { let changedBits = 0; if (prev.foo !== next.foo) changedBits |= 0b01; if (prev.bar !== next.bar) changedBits |= 0b10; return changedBits; }); // changedBits & unstable_observedBits !== 0 <StoreContext.Consumer unstable_observedBits={0b01}> {({foo}) => <div>{foo}</div> </StoreContext.Consumer> <StoreContext.Consumer unstable_observedBits={0b10}> {({bar}) => <div>{bar}</div> </StoreContext.Consumer>
https://medium.com/@koba04/a-secret-parts-of-react-new-context-api-e9506a4578aa
w 3FEVYBOE/FX$POUFYUBSFEJ⒎FSFOUMBZFST w SFBDUSFEVYNJHIUCFDIBOHFEXJUI/FX$POUFYU"1* w IUUQTHJUIVCDPNSFBDUKTSFBDUSFEVYQVMM w 8IZBSFZPVVTJOH3FEVY /FX$POUFYUBOE3FEVY
5IBOLT TQFBLFSEFDLDPNLPCB