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
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.1k
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
1.9k
Ready for React in 2019
koba04
2
1.8k
Algorithms in React
koba04
14
18k
Other Decks in Programming
See All in Programming
Vue × Nuxt × Oxc どこまで使える?実運用の現在地
andpad
0
300
ローカルLLMでどこまでコードが書けるか -拡張版 / How much code can be written on a local LLM Extended
kishida
12
4.4k
その問い、本当に正しいですか?AI時代のエンジニアに必要な哲学と認知科学 / ai-philosophy-cognitive-science
minodriven
13
6.2k
鹿野さんに聞く!『TypeScriptコードレシピ集』で磨く実践力
tonkotsuboy_com
2
730
技術記事、AIに書かせるか、自分で書くか? 〜それでも私が自分の手で書く理由〜 / #QiitaConference
jnchito
2
1.5k
1B+ /day規模のログを管理する技術
broadleaf
0
110
JavaDoc 再入門
nagise
1
410
Agentic UI
manfredsteyer
PRO
0
190
Honoでのサプライチェーン侵害対策 〜 3つのライブラリに学ぶ
yusukebe
7
1.4k
Javaの型とAI時代に型が大事な理由 / java types and type in AI era
kishida
2
150
Dataformのリポジトリを立ち上げるときにまずやること / dataform-day0-2026
snhryt
0
180
act1-costs.pdf
sumedhbala
0
100
Featured
See All Featured
Accessibility Awareness
sabderemane
1
140
The Mindset for Success: Future Career Progression
greggifford
PRO
0
370
Leveraging Curiosity to Care for An Aging Population
cassininazir
1
270
Testing 201, or: Great Expectations
jmmastey
46
8.2k
Stewardship and Sustainability of Urban and Community Forests
pwiseman
0
230
Lightning Talk: Beautiful Slides for Beginners
inesmontani
PRO
2
580
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
287
14k
Fireside Chat
paigeccino
42
4k
It's Worth the Effort
3n
188
29k
The Illustrated Guide to Node.js - THAT Conference 2024
reverentgeek
1
390
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
31
3.2k
Keith and Marios Guide to Fast Websites
keithpitt
413
23k
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