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
React v16 and beyond React Fiber
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
koba04
September 24, 2017
Programming
9.6k
11
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
React v16 and beyond React Fiber
HTML5 Conference 2016
http://events.html5j.org/conference/2017/9/session/#a4
koba04
September 24, 2017
More Decks by koba04
See All by koba04
フロントエンドの現在地とこれから
koba04
10
5.4k
Standing on the shoulders of giants
koba04
0
3.2k
React/Next によるアプリケーション開発のこれから
koba04
61
19k
フロントエンド刷新をプロジェクトとして進める際に気をつけていること
koba04
3
2k
How useEvent would change our applications
koba04
1
3.3k
kintoneフロントエンド刷新によるモノリスからの脱却とその先に目指す未来
koba04
3
16k
Make it Declarative with React
koba04
0
2k
Ready for React in 2019
koba04
2
1.8k
Algorithms in React
koba04
14
18k
Other Decks in Programming
See All in Programming
進化を続けるGo toolsの現在地 / The Current State of Ever-Evolving Go Tools
hond0413
0
160
壊れたパーサから始める関数型設計と構成的なパーサ #fp_matsuri
raiga0310
2
450
Detecting Compromised CI with eBPF and Cilium Tetragon
lizrice
0
160
GDG Korea Android: 2026 I/O Extended ~ What's new in Android development tools
pluu
0
220
Apache Hive: そしてCloud Native Lakehouseへ
okumin
1
210
Built Our Own Background Agent at LayerX
layerx
PRO
9
5k
言葉の格闘技のススメ~紙とペンと言葉から始める、キャリアの描き方~
progresscicada
2
140
Go 1.27 における memory allocation の高速化
andpad
0
110
複数の Claude Code が"放置"されてしまう問題をCLI ダッシュボードを自作して解決した話
sumihiro3
1
670
AI時代、エンジニアはどう育つのか -未経験エンジニアの成長を間近で見て考えたこと-
thasu0123
0
220
Laravel Boostに学ぶ、AIにPHPを書かせる技術 〜OSSの実装から蒸留するエージェント制御の王道〜
kentaroutakeda
3
670
仕様駆動開発へのトライを機に チームに適合する手法を模索し続けている話
freee
PRO
0
450
Featured
See All Featured
How to build a perfect <img>
jonoalderson
1
5.9k
Tips & Tricks on How to Get Your First Job In Tech
honzajavorek
1
680
Imperfection Machines: The Place of Print at Facebook
scottboms
270
14k
The Limits of Empathy - UXLibs8
cassininazir
1
600
The State of eCommerce SEO: How to Win in Today's Products SERPs - #SEOweek
aleyda
2
11k
Claude Code のすすめ
schroneko
67
230k
The Illustrated Children's Guide to Kubernetes
chrisshort
51
53k
Building Flexible Design Systems
yeseniaperezcruz
330
40k
Marketing Yourself as an Engineer | Alaka | Gurzu
gurzu
0
270
Data-driven link building: lessons from a $708K investment (BrightonSEO talk)
szymonslowik
1
1.2k
Thoughts on Productivity
jonyablonski
76
5.3k
<Decoding/> the Language of Devs - We Love SEO 2024
nikkihalliwell
1
280
Transcript
3FBDUWBOECFZPOE3FBDU'JCFS )5.-$POGFSFODF !LPCB
!LPCB
!LPCB
w 3FBDUWͰͷมߋ w 3FBDU'JCFS w 8IBU w 8IZ
w )PX "HFOEB
3FBDUW
w ͿΓͷϝδϟʔόʔδϣϯΞοϓ w WͷϦϦʔεɺ w ޓੑΛอͪͳ͕Βͷ෦࣮ͷॻ͖͑ˠ3FBDU'JCFS w WΛ͍ͬͯΕεϜʔζʹΞοϓσʔτͰ͖Δʢͣʣ w XBSOJOHCSFBLJOHDIBOHFͷྲྀΕ
w ͨͩ͠ɺ%0.ͷѻ͍ϥΠϑαΠΫϧΠϕϯτͷॱ൪ͳͲͰϋ ϚΔ߹͋Δ͔ w ϥΠηϯε͕#4% 1BUFOT͔Β.*5ʹ/FX 3FBDUW
w #4% 1BUFOT͔Β.*5ʹ -JDFOTF IUUQTDPEFGBDFCPPLDPNQPTUTSFMJDFOTJOHSFBDUKFTUqPXBOEJNNVUBCMFKT
/FX'FBUVSFTJOW
3FOEFSTUSJOHBOEBSSBZ
w SFOEFS͔ؔΒจࣈྻྻΛฦ͢͜ͱ͕Ͱ͖ΔΑ͏ʹ 3FOEFSTUSJOHBOEBSSBZ // จࣈྻ const DisplayName = ({user}) =>
`${user.name} (@${user.id})`; <DisplayName user={{name: ‘Toru Kobayashi’, id: ‘koba04’}} /> // Toru Kobayashi (@koba04) // ྻ const Row = ({children}) => <tr>{children}</tr>; const Columns = ({items}) => ( items((item, i) => <td key={i}>{item}</td> ); <Row> <Columns items={[‘foo’, ‘bar’, ‘baz’]} /> </Row>
w +49ͰγϯλοΫεͱͯ͠αϙʔτ͢Δͱ͍͏ٞ w 4VQQPSUTUBOEBMPOFGSBHNFOUTZOUBY w IUUQTHJUIVCDPNGBDFCPPLKTYJTTVFT 3FOEFSTUSJOHBOEBSSBZ [ <Child key={1}
/>, <Child key={2} />, <Child key={3} /> ] !!! <> <Child /> <Child /> <Child /> </>
&SSPS#PVOEBSJFT
w USZDBUDIͷ༷ʹɺࢠ$PNQPOFOUͷSFOEFSϥΠϑαΠΫϧϝ ιουͰى͖ͨΤϥʔΛΩϟον͢ΔͨΊͷϥΠϑαΠΫϧϝ ιου͕Ճ w ˠDPNQPOFOU%JE$BUDI w W͔ΒࢠSFOEFSϥΠϑαΠΫϧϝιουͰى͖ͨΤϥʔͷ ѻ͍͕มΘΔ &SSPS#PVOEBSJFT
w W·ͰɺSFOEFSϥΠϑαΠΫϧϝιουͰΤϥʔ͕ى͖ ͯ$PNQPOFOUͦͷ·· w ˠෆ߹ͳ7JFXΛϢʔβʔʹදࣔͯ͠͠·͏Մೳੑ w WͰɺΤϥʔ͕ൃੜͨ͠Β3FBDU%0.SFOEFSͰࢦఆͨ͠ SPPUDPOUBJOFS͔ΒΞϯϚϯτ͢Δ w ˠΞϯϚϯτ͞Εͨ͘ͳ͍߹ΤϥʔΛϋϯυϦϯά͢
Δඞཁ͕͋Δ &SSPS#PVOEBSJFT
&SSPS#PVOEBSJFT class Child extends React.Component { componentDidMount() { throw new
Error(‘Something went wrong!!’); } } class App extends React.Component { constructor(props) { super(props); this.state = { error: null }; } componentDidCatch(error, info) { // info.componentStackComponentͷStackTraceจࣈྻ this.setState(() => ({error})); } render() { return this.state.error ? <p>Τϥʔ͕ൃੜ͠·ͨ͠</p> : <Child />; } }
1PSUBM
w 3FBDU%0.DSFBUF1PSUBM w ҙͷ%0.ʹର͢ΔSFOEFSΛ$PNQPOFOUπϦʔͷҰ෦ͱ͠ ͯѻ͏͜ͱ͕Ͱ͖Δ w ϥΠϑαΠΫϧϝιουͳͲ௨ৗͷࢠ$PNQPOFOUͱಉ༷ʹ ѻΘΕΔ 1PSUBM
w 1PSUBMΛΘͳ͍ྫ 1PSUBM class App extends React.Component { componentDidUpdate() {
const container = document.querySelector(‘.modal-container’); if (this.state.modal) { ReactDOM.render( <Modal type={this.state.modal} onClose={() => { this.setState( () => ({modal: null}), () => ReactDOM.unmountComponentAtNode(container) ); }} />, container ); } } }
w 1PSUBMΛͬͨ߹ 1PSUBM class App extends React.Component { render() {
return ( <section> <Contents /> {this.state.modal && ReactDOM.createPortal( <Modal type={this.state.modal} onClose={() => { this.setState(() => ({modal: null})); } />, document.querySelector(‘.modal-container’) )} </section> ); } }
'MBU#VOEMFT
w #SPXTFSJGZΛͬͨϏϧυ͔Β3PMMVQΛͬͨϏϧυʹ w ̍ͭͷϞδϡʔϧͱͯ͠Ϗϧυ͢Δ͜ͱͰɺϑΝΠϧαΠζͷ ݮɺύʔεʹ͔͔Δ࣌ؒΛݮ w ͜ͷ݁ՌɺASFBDUMJCYYYAͷΑ͏ͳ෦Ϟδϡʔϧͷࢀ রʢ%JSFDU*NQPSUʣ͕ෆՄೳʹ w ґଘ͍ͯ͠ΔSEQBSUZMJCSBSZରԠ͕ඞཁ
w SFBDUUBQFWFOUQMVHJO SFBDUOBUJWFXFCʜ 'MBU#VOEMFT
'MBU#VOEMFT node_modules/react "## cjs $ "## react.development.js $ %## react.production.min.js
"## index.js node_modules/react-dom "## cjs $ "## react-dom-server.browser.development.js $ "## react-dom-server.browser.production.min.js $ "## react-dom-server.node.development.js $ "## react-dom-server.node.production.min.js $ "## react-dom-test-utils.development.js $ "## react-dom-unstable-native-dependencies.development.js $ "## react-dom-unstable-native-dependencies.production.min.js $ "## react-dom.development.js $ %## react-dom.production.min.js "## index.js
4FSWFS4JEF3FOEFSJOH
w શʹಠཱͨ͠3FOEFSFSʹʢطଘ࣮͕ϕʔεʣ w 3FBDU1BSUJBM3FOEFSFSKTͱ͍͏ϑΝΠϧ - ʹ w 4USFBN3FOEFSJOHͷαϙʔτ w )ZESBUJPO4USBUFHZͷมߋ
w )ZESBUJPOʜ443ͨ͠)5.-ΛΫϥΠΞϯτͰͷϨϯμϦ ϯά࣌ʹ࠶ར༻͢Δ w 3FBDU%0.IZESBUF ͷՃ 4FSWFS4JEF3FOEFSJOH
w SFOEFS5P/PEF4USFBN SFOEFS5P4UBUJD/PEF4USFBNͷՃ 4USFBN3FOEFSJOH import ReactDOMServer from ‘react-dom/server’; const App
= () => ( <div> <p>Hello Stream!</p> </div> ); ReactDOMServer.renderToNodeStream(<App />).pipe(process.stdin); // <div data-reactroot=""><p>Hello Stream!</p></div> ReactDOMServer.renderToStaticNodeStream(<App />).pipe(process.stdin); // <div><p>Hello Stream!</p></div>
w 3FBDU%0.IZESBUF ͱ͍͏໌ࣔతͳ"1*ͷՃ w WͰɺ3FBDU%0.SFOEFS ʹΑΔ)ZESBUFҾ͖ଓ͖ αϙʔτʢAEBUBSFBDUSPPUAଐੑʹΑͬͯఆʣ w 3FBDU&MFNFOUͷ୯ҐͰՄೳͳݶΓ࠶ར༻͞ΕΔΑ͏ʹ w
W·Ͱɺ%0.ߏ͕શʹҰக͢Δ͔Ͳ͏͔ΛνΣο ΫαϜʹΑͬͯఆ w /PNPSFAEBUBSFBDUDIFDLTVNABOEAEBUBSFBDUJEA )ZESBUJPO4USBUFHZ
%0."UUSJCVUFT
w ϗϫΠτϦετʹͳ͍ଐੑ%0.ʹө͞ΕΔΑ͏ʹ w WͰɺXBSOJOHTUSJQ w ADMBTTAAGPSAAPOʙAͳͲআ͘ w ෆਖ਼ͳܕͷଐੑTUSJQ͞ΕΔΑ͏ʹ w WͰɺจࣈྻԽͯ͠ద༻͞Ε͍ͯͨ
%0."UUSJCVUFT <div someExperimentalAttribute=“foo” /> <div className={false} /> // v16 <div /> & warning // v15 <div className=“false” /> .PSFIUUQTGBDFCPPLHJUIVCJPSFBDUCMPHEPNBUUSJCVUFTJOSFBDUIUNM
1PMZpMM
w .BQ 4FU SFRVFTU"OJNBUJPO'SBNF͕ඞཁʹ w αϙʔτ͢ΔϒϥβʔʹԠͯ͡1PMZpMMΛೖΕΔ 1PMZpMM import ‘core-js/es6/map’; import
‘core-js/es6/set’; import raf from ‘raf’; if (!window.requestAnimationFrame) { window.requestAnimationFrame = raf; }
0UIFS$IBOHFT
w 3FBDUDSFBUF$MBTT 3FBDU1SPQ5ZQFTͷআ w "EEPOϏϧυͷআ w ͍͔ͭ͘ͷέʔεͰɺߋ৽࣌ͷ"1*ݺͼग़͠ॱ͕มߋʹ w TFU4UBUFͷίʔϧόοΫɺϥΠϑαΠΫϧϝιουɺ3FG w
IUUQTHJUIVCDPNGBDFCPPLSFBDUCMPCNBTUFS $)"/(&-0(NE <6OSFMFBTFE>TFDUJPO 0UIFS$IBOHFT
8IFO
.BZCFOFYUXFFL
3FBDU'JCFS
w 3FBDUͷίΞΞϧΰϦζϜͷ࠶࣮ w ࠷ॳͷ13 w طଘͷ࣮ͱޓੑΛอͪͳ͕ΒɺॊೈͳεέδϡʔϦϯάΛ Մೳʹ w WͰɺޓੑͷ͋Δঢ়ଶͰϦϦʔε͞ΕͯɺPQUJOͰඇಉ ظ3FOEFSJOH͕Մೳʹ
w ඇಉظ3FOEFSJOHपΓ࣮த 3FBDU'JCFSͱ
طଘ࣮ͷ
w ߋ৽ॲཧ͕શͯಉظతɻπϦʔશମͷࠩͷݕग़ʙ%0.ͷ өɺϥΠϑαΠΫϧϝιουͷݺͼग़͕͠શͯಉظͰ࣮ߦ͞ ΕΔ طଘ࣮ͷ <App /> <div /> <Button
/> <List /> <Item /> <Item /> <Item /> ࠶ؼత & ಉظత ↓ UIΛϒϩοΫ͢Δ & ϑϨʔϜམͪ mount mount mount
طଘ࣮ͷ Key Input API Response Ωʔೖྗ͕ ϒϩοΫ αʔόʔ͔Βͷ ϨεϙϯεΛॲཧ Key
Input Key Input Key Input Key Input
3FBDU'JCFSʹΑΔղܾํ๏
w ߋ৽ॲཧΛεέδϡʔϦϯάՄೳʹ w ߋ৽ॲཧʹର͢Δ༏ઌ͚ w $PNQPOFOUʹର͢Δ༏ઌ͚ 3FBDU'JCFSʹΑΔղܾํ๏ ୯७ͳॲཧͷߴԽͰͳ͘ɺ 6*ͷϨεϙϯεੑΛ্ͤ͞Δ͜ͱ͕త
3FBDU'JCFSʹΑΔղܾํ๏ Key Input ߋ৽Λ Chunkʹ ղͯ͠ద༻ Key Input Key Input
Key Input API Response ༏ઌߴ ༏ઌ
3FBDU"SDIJUFDUVSF
3FBDU"SDIJUFDUVSF <div /> Component + JSX Reconciler Renderer <App />
<Text /> Fiber Stack DOM Native View Canvas
w 3FBDU&MFNFOUͷπϦʔΛߏங͢Δ w $PNQPOFOUΛϚϯτɺߋ৽ɺΞϯϚϯτ͢Δ w ϥΠϑαΠΫϧϝιουΛݺͼग़͢ w ࠩΛܭࢉ͢Δ w 3FOEFSFSʹࠩΛ͑Δ
w ॴҦɺ7JSUVBM%0.ͱݴΘΕ͍ͯͨ෦ 3FDPODJMFS
4DIFEVMJOH
w ࣌ؒϕʔεͷεέδϡʔϦϯά w SFRVFTU*EMF$BMMCBDLΛͬͨεέδϡʔϦϯά w ༏ઌϕʔεͷεέδϡʔϦϯά w ߴ༏ઌͷߋ৽ɺ༏ઌͷߋ৽ʹׂΓࠐΉ͜ͱ͕Ͱ͖Δ w ׂΓࠐ·Εͨߋ৽ॲཧޙ͔Β࠶։Ͱ͖Δ
w ݱ࣌Ͱ༏ઌͱͯ͠ɺl4ZODz l5BTLz l)JHIz l-PXz l0⒎4DSFFOz͕ఆٛ͞Ε͍ͯΔ 4DIFEVMJOH
SFRVFTU*EMF$BMMCBDL const work = (deadline) => { if (deadline.timeRemaining() >
10) { // do some heavy tasks } else { requestIdleCallback(work); } }; requestIdleCallback(work); Fig. 1 Example of an inter-frame idle period (https://www.w3.org/TR/requestidlecallback/)
'JCFSͷσʔλߏ
'JCFSͷσʔλߏ export type Fiber = {| tag: TypeOfWork, key: null
| string, type: any, stateNode: any, return: Fiber | null, child: Fiber | null, sibling: Fiber | null, index: number, ref: null | (((handle: mixed) => void) & {_stringRef: ?string}), pendingProps: any, memoizedProps: any, updateQueue: UpdateQueue | null, memoizedState: any, internalContextTag: TypeOfInternalContext, effectTag: TypeOfSideEffect, nextEffect: Fiber | null, firstEffect: Fiber | null, lastEffect: Fiber | null, pendingWorkPriority: PriorityLevel, alternate: Fiber | null, _debugID?: DebugID, _debugSource?: Source | null, _debugOwner?: Fiber | ReactInstance | null, _debugIsCurrentlyTiming?: boolean, |};
-JOLFE-JTUߏ let root = fiber; let node = fiber; while
(true) { // Do something with node if (node.child) { node = node.child; continue; } if (node === root) { return; } while (!node.sibling) { if (!node.return || node.return === root) { return; } node = node.return; } node = node.sibling; } From: Fiber Principles: Contributing To Fiber #7942 https://github.com/facebook/react/issues/7942
Text = () => '...'; List = () => [
<div>...</div>, <div>...</div>, ]; class App extends React.Component { render() { return ( <main> <h2>...</h2> <div> <Text /> <List /> </div> </main> ); } } ReactDOM.render(<App />, container) HostRoot <App /> <main /> <h2 /> <div /> <Text /> HostText List <div /> <div /> 1 2 3 4 5 6 8 9 10 7 Ͳ͔͜ΒͰதஅʙ࠶։ Ͱ͖Δ
1IBTFT
w 3FBDU'JCFSl#FHJOz l$PNQMFUFz l$PNNJUzͷϑΣʔζΛ࣋ͬͯ ͍Δ w #FHJOʙ$PNQMFUF w 'JCFS $PNQPOFOU
ͷ୯ҐͰॲཧ͞ΕΔ w Πϯελϯεͷ࡞ɺSFOEFSؔͷ࣮ߦ ࠩܭࢉ w $PNNJU w ߋ৽ॲཧͷ୯ҐͰॲཧ͞ΕΔ w ෭࡞༻Λ·ͱΊͯө͢Δ %0.ͷߋ৽ͳͲ 1IBTFT
w #FHJOϑΣʔζ w DPNQPOFOU8JMM.PVOU DPNQPOFOU8JMM3FDFJWF1SPQT TIPVME$PNQPOFOU6QEBUF DPNQPOFOU8JMM6QEBUF w ඇಉظ3FOEFSJOHͰɺதஅʙ࠶։͞ΕΔ͜ͱͰෳճݺ
ΕΔ͜ͱ w $PNNJUϑΣʔζ w DPNQPOFOU%JE.PVOU DPNQPOFOU%JE6QEBUF DPNQPOFOU8JMM6ONPVOU ϥΠϑαΠΫϧϝιου
෭࡞༻·ͱΊͯҰͰө͞ΕΔ FiberA FiberB FiberD FiberE Commit all SideEffects Idle Time
Idle Time Idle Time Beginʙ Complete SideEffect SideEffect SideEffect Host (DOM) FiberC
1SJPSJUZ
)JHI1SJPSJUZͷߋ৽ॲཧׂΓࠐΈͰ͖Δ FiberA FiberB FiberA FiberC Commit Low Priority High Priority
Commit FiberA FiberB FiberC Low Priority ࠶ར༻ ׂΓࠐΈʂ தஅ
σϞ https://koba04.github.io/react-fiber-resources/examples/
4UBDLSFDPODJMFS
4ZOD1SJPSJUZʹΑΔߋ৽
-PX1SJPSJUZʹΑΔߋ৽ॲཧ BeginʙComplete Commit
0⒎4DSFFO1SJPSJUZ TabA TabB hidden hidden Viewport hidden
w %0.3FOEFSFSͷ߹ɺIJEEFO1SPQΛ͏ 0⒎4DSFFO1SJPSJUZ App = () => ( <div> <ul
hidden> <li>xxx</li> : 1000items <li>xxx</li> </ul> <ul> <li>xxx</li> : 1000items <li>xxx</li> </ul> </div> ); ReactDOM.render(<App />, container);
w %0.3FOEFSFSͷ߹ɺIJEEFO1SPQΛ͏ 0⒎4DSFFO1SJPSJUZ App = () => ( <div> <ul
hidden> <li>xxx</li> : 1000items <li>xxx</li> </ul> <ul> <li>xxx</li> : 1000items <li>xxx</li> </ul> </div> ); ReactDOM.render(<App />, container); ݱ࣌ͰɺFeatureϑϥάʹΑͬͯӅ͞Ε͍ͯΔ
ඇಉظ3FOEFSJOHΛࢼ͢
w 3FBDU%0.VOTUBCMF@EFGFSSFE6QEBUFTΛͬͨ-PX 1SJPSJUZʹΑΔߋ৽ w 3FBDUVOTUBCMF@"TZOD$PNQPOFOUΛͬͯߋ৽Λ-PX 1SJPSJUZʹ w 3FBDU%0.'FBUVSF'MBHTpCFS"TZOD4DIFEVMJOHΛ༗ޮʹ͠ ͯσϑΥϧτΛ-PX1SJPSJUZʹ w
0⒎4DSFFO1SJPSJUZར༻Մೳʹ w 3FBDU%0.qVTI4ZOD ඇಉظ3FOEFSJOHΛࢼ͢
ඇಉظ3FOEFSJOHΛࢼ͢ // Low PriorityʹΑΔߋ৽ ReactDOM.unstable_deferredUpdates(() => { this.setState(updater); }); //
ߋ৽͕Low Priorityͱͯ͠ѻΘΕΔComponent const AsyncComponent = React.unstable_AsyncComponent; <AsyncComponent> <App /> </AsyncComponent> // or class App extends AsyncComponent { onClick() { // Sync Priority ReactDOM.flushSync(() => this.setState(() => newState)); } }
ඇಉظ3FOEFSJOHΛࢼ͢ // Low PriorityʹΑΔߋ৽ ReactDOM.unstable_deferredUpdates(() => { this.setState(updater); }); //
ߋ৽͕Low Priorityͱͯ͠ѻΘΕΔComponent const AsyncComponent = React.unstable_AsyncComponent; <AsyncComponent> <App /> </AsyncComponent> // or class App extends AsyncComponent { onClick() { // Sync Priority ReactDOM.flushSync(() => this.setState(() => newState)); } } v17Ҏ߱ͰͷAPIݱ࣌Ͱະఆ
$VTUPN3FOEFSFS
w $VTUPN3FOEFSFSΛ࣮͢ΔͨΊͷํ๏͕ఏڙ͞ΕΔ w ASFBDUSFDPODJMFSA w 3FBDUSFDPODJMFSQBDLBHF w IUUQTHJUIVCDPNGBDFCPPLSFBDUQVMM w
'MPXUZQFʹΑͬͯΠϯλʔϑΣΠε͕ఆٛ͞Ε͍ͯΔ w IUUQTHJUIVCDPNGBDFCPPLSFBDUCMPCNBTUFSTSD SFOEFSFSTTIBSFEpCFS3FBDU'JCFS3FDPODJMFSKT $VTUPN3FOEFSFS
$VTUPN3FOEFSFS $POTPMF ReactConsole.render( <div> <red>Hello</red> <yellow>World</yellow> <cyan>React</cyan> <rainbow>Custom Renderer!</rainbow> </div>,
() => console.log( colors.inverse('##### Update ######’) ) ); ReactConsole.render( <div> <green>Hello</green> <yellow>World2</yellow> <cyan>React</cyan> </div> ); IUUQTHJTUHJUIVCDPNLPCBDCECEGBFDB
$VTUPN3FOEFSFS 7PJDF ReactVoice.render([ <alex key={1}>Hello</alex>, <victoria key={2}>React Fiber</victoria>, <kyoko key={3}>͜Μʹͪ
HTML5 Conference</kyoko>, ]); ??? IUUQTHJTUHJUIVCDPNLPCBFBGDBFBDEFGE
ಠࣗʹ3FBDU%0.-JUFΛ࣮Ͱ͖Δʂ
'VUVSF
w WͰɺඇಉظ3FOEFSJOH -PX1SJPSJUZ ͕σϑΥϧτʹ w %ZOBNJDJNQPSUΛ1SPNJTF$PNQPOFOUͱͯ͠αϙʔτʁ w 3FBTPO3FBDU͔Βͷ1PSU 3FEVDFSFUD
w কདྷతʹ3FBDU'JCFSΛผݴޠͰ࣮͢ΔՄೳੑʁ 'VUVSF
'VUVSF React Fiber (written by C or C++ or…) Native
module for ReactNative Web Assembly for ReactDOM
·ͱΊ
w W3FBDU'JCFS͕ΘΕΔॳΊͯͷόʔδϣϯ w Wͷ࣌Ͱɺ3FBDU'JCFSʹΑͬͯܶతʹߴԽ͞ΕΔ͜ͱ ͳ͍ɻࠓޙͷͨΊͷΠϯϑϥ w 3FBDU'JCFSɺ6*ͷϨεϙϯεੑΛεέδϡʔϦϯάʹΑͬ ্ͯͤ͞Δ ·ͱΊ
5IBOLT TQFBLFSEFDLDPNLPCB