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.4k
React/Next によるアプリケーション開発のこれから
koba04
59
16k
フロントエンド刷新をプロジェクトとして進める際に気をつけていること
koba04
3
1.6k
How useEvent would change our applications
koba04
1
2.7k
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
220
Other Decks in Programming
See All in Programming
TDDと今まで
kanayannet
0
110
導入から5年が経って見えた Datadog APM 運用の課題
bgpat
1
480
Jakarta EE 11 - Performance and Developer Productivity
ivargrimstad
0
840
before_rails_girls_after_rails_girls
maimux2x
0
300
Next.js で SPA を構築する際の辛み
hayatow
0
220
phpunit/php-code-coverageって何をしてるんだ #phperkaigi
o0h
PRO
2
190
オレオレkaggle開発環境に Formatter/Linter入れてみた
stgkrt
0
350
Cloud RunとCloud PubSubでサーバレスなデータ基盤2024 with Terraform / Cloud Run and PubSub with Terraform
shinyorke
7
1.7k
シェルの履歴とイクンリメンタル検索を使う
naoya
7
2.3k
TerraformをやめてCDKでReStartしたあと、 CDKをやめてCDK for TerraformでReStartした話
tmiura0203
0
770
Docker ハンズオン / docker-hands-on
suzukihoge
48
15k
Laravel標準バリデーションでできること
hmb_ok
1
330
Featured
See All Featured
Product Roadmaps are Hard
iamctodd
43
9.6k
BBQ
matthewcrist
78
8.7k
The Mythical Team-Month
searls
214
42k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
11
1.4k
Building Your Own Lightsaber
phodgson
97
5.6k
Debugging Ruby Performance
tmm1
68
11k
Large-scale JavaScript Application Architecture
addyosmani
501
110k
The Art of Programming - Codeland 2020
erikaheidi
40
12k
A designer walks into a library…
pauljervisheath
199
23k
Fireside Chat
paigeccino
19
2.5k
Optimising Largest Contentful Paint
csswizardry
7
2.3k
Visualization
eitanlees
135
14k
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