Slide 1

Slide 1 text

$BQBCJMJUZPG3FBDU'JCFS /PEFֶԂ !LPCB

Slide 2

Slide 2 text

!LPCB

Slide 3

Slide 3 text

$POUSJCVUJOH3FBDU'JCFS

Slide 4

Slide 4 text

$POUSJCVUJOHUP3FBDU'JCFS (facebook/react) ➜ git shortlog -sn --grep [fF]iber 123 Sebastian Markbåge 82 Andrew Clark 38 Dan Abramov 30 Brian Vaughn 28 Ben Alpert 14 Dominic Gannaway 9 Toru Kobayashi 4 Sasha Aickin 4 Flarnie Marchan 4 Dustan Kasten 4 Brandon Dail 3 Tom Occhino 3 Robin Ricard 2 Vjeux :

Slide 5

Slide 5 text

http://blog.koba04.com/post/2017/04/25/a-state-of-react-fiber/

Slide 6

Slide 6 text

https://html5experts.jp/shumpei-shiraishi/23265/

Slide 7

Slide 7 text

5IFpSTU13PG3FBDU'JCFS

Slide 8

Slide 8 text

$BWFBU

Slide 9

Slide 9 text

w 3FBDU'JCFS`TBTZODISPOPVTXPSLJTTUJMMJOVOEFS EFWFMPQNFOU w 5IFJNQMFNFOUBUJPOIBTCFFODIBOHJOH w 5IFDIBOHFTBSFSFMBUFEUPBTZODISPOPVTXPSL FOBCMFEJOW w 4PNFGFBUVSFT*`NHPOOBUPJOUSPEVDFJOUIJT QSFTFOUBUJPOBSFOPUFOBCMFEJOW $BWFBU

Slide 10

Slide 10 text

No content

Slide 11

Slide 11 text

"SDIJUFDUVSFPG3FBDU

Slide 12

Slide 12 text

Component + JSX Reconciler Renderer Fiber Stack DOM Native View Canvas

Slide 13

Slide 13 text

8IBUJT3FDPODJMJBUJPO

Slide 14

Slide 14 text

w #VJME3FBDU&MFNFOUUSFFT w .PVOU 6QEBUF 6ONPVOUDPNQPOFOUT w $BMMJOHMJGFDZDMFNFUIPET w $PNQVUFDIBOHFT w 5FMMBSFOEFSFSDIBOHFTʜ w *UXBTDBMMFE7JSUVBM%0. 3FDPODJMJBUJPO

Slide 15

Slide 15 text

8IBUJT3FBDU'JCFS

Slide 16

Slide 16 text

w 3FBDU'JCFSJTBOFXSFDPODJMJBUJPOBMHPSJUIN w &OBCMFTDIFEVMJOHVQEBUFT w *U`TQPTTJCMFUPSFUVSOBOBSSBZ TUSJOHTGSPNSFOEFS NFUIPEEJSFDUMZ w 1PSUBMT &SSPSCPVOEBSJFT $PSPVUJOF$PNQPOFOUʜ w .BLFT6*SFTQPOTJWFOFTT w /PUGPSTQFFEUIBUCFODINBSLTNFBTVSF 3FBDU'JCFS

Slide 17

Slide 17 text

3FBDU'JCFSJTB-JOLFE-JTU 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, // This type will be more specific once we overload the tag. memoizedProps: any, // The props used to create the output. updateQueue: UpdateQueue | null, memoizedState: any, internalContextTag: TypeOfInternalContext, effectTag: TypeOfSideEffect, nextEffect: Fiber | null, firstEffect: Fiber | null, lastEffect: Fiber | null, pendingWorkPriority: PriorityLevel, progressedPriority: PriorityLevel, progressedChild: Fiber | null, progressedFirstDeletion: Fiber | null, progressedLastDeletion: Fiber | null, alternate: Fiber | null, };

Slide 18

Slide 18 text

3FBDU'JCFSJTB-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

Slide 19

Slide 19 text

3FBDU5ZQF0G8PSLKT module.exports = { IndeterminateComponent: 0, // Before we know whether it is functional or class FunctionalComponent: 1, ClassComponent: 2, HostRoot: 3, // Root of a host tree. Could be nested inside another node. HostPortal: 4, // A subtree. Could be an entry point to a different renderer. HostComponent: 5, HostText: 6, CoroutineComponent: 7, CoroutineHandlerPhase: 8, YieldComponent: 9, Fragment: 10, };

Slide 20

Slide 20 text

8IZJT3FBDU'JCFSOFDFTTBSZ

Slide 21

Slide 21 text

w $VSSFOUJNQMFNFOUBUJPOJTUSBWFSTJOH3FBDU&MFNFOUUSFF SFDVSTJWFMZBOETZODISPOPVTMZ 8IZJT3FBDU'JCFSOFDFTTBSZ
Recursive & Synchronously ↓ Blocking UI & Drop frames mount mount mount

Slide 22

Slide 22 text

8IBUJT4DIFEVMJOH

Slide 23

Slide 23 text

w 5JNFCBTFTDIFEVMJOH w 4DIFEVMJOHXJUISFRVFTU*EMF$BMMCBDL w 1SJPSJUZCBTFTDIFEVMJOH w )JHIQSJPSJUZVQEBUFTDBOJOUFSSVQUUPMPXQSJPSJUZ VQEBUFT w 3FBDU'JCFSJTBCMFUPSFTVNFJOUFSSVQUFEVQEBUFTMBUFS w 1SJPSJUJFTBSF4ZOD 5BTL )JHI -PXBOE0⒎4DSFFO 8IBUJT4DIFEVMJOH

Slide 24

Slide 24 text

w 3FBDU'JCFSIBTCFHJO DPNQMFUF DPNNJUQIBTFT w #FHJO8PSLʙ$PNQMFUF8PSL w #FQSPDFTTFEQFS'JCFS w $SFBUF*OTUBODF 3FOEFS3FBDU&MFNFOU $PNQVUFDIBOHFT w $PNNJU8PSL w #FQSPDFTTFEQFSVQEBUF w 'MVTIBMM4JEF&⒎FDUT 6QEBUF)PTUJOTUBODFTʜ 1IBTFT

Slide 25

Slide 25 text

w *O#FHJO8PSL w DPNQPOFOU8JMM.PVOU DPNQPOFOU8JMM3FDFJWF1SPQT TIPVME$PNQPOFOU6QEBUF DPNQPOFOU8JMM6QEBUF w 5IFTFNBZCFDBMMFETFWFSBMUJNFT w *O$PNNJU8PSL w DPNQPOFOU%JE.PVOU DPNQPOFOU%JE6QEBUF DPNQPOFOU8JMM6ONPVOU -JGFDZDMFNFUIPET

Slide 26

Slide 26 text

1IBTFT Fiber Fiber Fiber Fiber CommitWork Beginʙ CompleteWork Beginʙ CompleteWork … SideEffect SideEffect SideEffect Host (DOM)

Slide 27

Slide 27 text

4JEF&⒎FDU module.exports = { // Don't change these two values: NoEffect: 0, // 0b00000000 PerformedWork: 1, // 0b00000001 // You can change the rest (and add more). Placement: 2, // 0b00000010 Update: 4, // 0b00000100 PlacementAndUpdate: 6, // 0b00000110 Deletion: 8, // 0b00001000 ContentReset: 16, // 0b00010000 Callback: 32, // 0b00100000 Err: 64, // 0b01000000 Ref: 128, // 0b10000000 };

Slide 28

Slide 28 text

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/)

Slide 29

Slide 29 text

'MVTIBMMVQEBUFTBUPODF BWPJEKBOL Fiber Fiber Fiber Fiber Fiber Fiber Commit all SideEffects Idle Time Idle Time Idle Time Beginʙ Complete Work SideEffect SideEffect SideEffect Host (DOM)

Slide 30

Slide 30 text

Text = () => '...'; List = () => [
...
,
...
, ]; class App extends React.Component { render() { return (

...

); } } ReactDOM.render(, container) HostRoot

HostText List
1 2 3 4 5 6 8 9 10 7 Stop and resume anywhere!

Slide 31

Slide 31 text

*OUFSSVQUBIJHIQSJPSJUZVQEBUF FiberA FiberB FiberA FiberC Commit Low Priority High Priority Commit FiberA FiberB FiberC Low Priority Reuse Interrupted Resume

Slide 32

Slide 32 text

%FNP https://koba04.github.io/react-fiber-resources/examples/

Slide 33

Slide 33 text

4UBDLSFDPODJMFS

Slide 34

Slide 34 text

'JCFSSFDPODJMFSXJUITZODQSJPSJUZ

Slide 35

Slide 35 text

'JCFSSFDPODJMFSXJUIMPXQSJPSJUZ BeginʙCompleteWork CommitWork

Slide 36

Slide 36 text

https://blogs.windows.com/msedgedev/2017/06/01/input-responsiveness-event-loop-microsoft-edge/

Slide 37

Slide 37 text

0⒎4DSFFO1SJPSJUZ w 6TJOHIJEEFOQSPQPO)PTU$PNQPOFOU 3FBDU%0.'JCFS TabA TabB hidden hidden Viewport hidden

Slide 38

Slide 38 text

0⒎4DSFFO1SJPSJUZ App = () => (
  • xxx
  • : 1000items
  • xxx
  • xxx
  • : 1000items
  • xxx
); ReactDOM.render(, container);

Slide 39

Slide 39 text

0⒎4DSFFO1SJPSJUZ Low priority Offscreen priority Commit Work

Slide 40

Slide 40 text

8IBUBCPVU443

Slide 41

Slide 41 text

w "OFXTFSWFSSFOEFSFSJTJOEFQFOEFOUSFOEFSFS XIJDI EPFTO`UVTF'JCFSSFDPODJMFS w IUUQTHJUIVCDPNGBDFCPPLSFBDUCMPCNBTUFSTSD SFOEFSFSTTIBSFETFSWFS3FBDU1BSUJBM3FOEFSFSKT w 5IFTFSWFSSFOEFSFSTVQQPSUTTUSFBNJOH"1* 8IBUBCPVU443 import ReactDOMNodeStream from ‘react-dom/node-stream’; ReactDOMNodeStream.renderToStream(); // ReactDOMNodeStream.renderToStaticStream();

Slide 42

Slide 42 text

3FBDU1BSUJBM3FOEFSFSKT read(bytes) { if (this.exhausted) { return null; } var out = ''; while (out.length < bytes) { if (this.stack.length === 0) { this.exhausted = true; break; } var frame = this.stack[this.stack.length - 1]; if (frame.childIndex >= frame.children.length) { out += frame.footer; this.stack.pop(); if (frame.tag === 'select') { this.currentSelectValue = null; } continue; } var child = frame.children[frame.childIndex++]; out += this.render(child, frame.context); } return out; }

Slide 43

Slide 43 text

)PXEP*CVJMEBDVTUPNSFOEFSFS

Slide 44

Slide 44 text

w $VTUPNSFOEFSFSJOUFSGBDFJTEFpOFECZ'MPXUZQFJO 3FBDU'JCFS3FDPODJMFS w IUUQTHJUIVCDPNGBDFCPPLSFBDUCMPCNBTUFSTSD SFOEFSFSTTIBSFEpCFS3FBDU'JCFS3FDPODJMFSKT w $VSSFOUMZ UIFSFJTOPXBZUPVTF3FBDU'JCFS3FDPODJMFSGSPN PVUTJEF3FBDU w 3'$3FBDU'JCFS3FDPODJMFSSFMFBTFBSUJGBDU w IUUQTHJUIVCDPNGBDFCPPLSFBDUJTTVFT w l*UXJMMCFTVQQPSUFEBTQVCMJD"1*z )PXEP*CVJMEBDVTUPNSFOEFSFS

Slide 45

Slide 45 text

getRootHostContext(), getChildHostContext(), getPublicInstance() createInstance() appendInitialChild(), finalizeInitialChildren() prepareUpdate(), commitUpdate(), commitMount() shouldSetTextContent(), resetTextContent() shouldDeprioritizeSubtree() createTextInstance(), commitTextUpdate() appendChild(), appendChildToContainer() insertBefore(), insertInContainerBefore() removeChild(), removeChildFromContainer() scheduleDeferredCallback() prepareForCommit(), resetAfterCommit() // Optional canHydrateInstance(), canHydrateTextInstance() getNextHydratableSibling(), getFirstHydratableChild() hydrateInstance(), hydrateTextInstance() useSyncScheduling: boolean See: https://gist.github.com/koba04/3c03f94dfe1ee686a12a4a033a3dac67

Slide 46

Slide 46 text

w $POTPMFSFOEFSFS w IUUQTHJTUHJUIVCDPN LPCBDCECEGBFDB w 7PJDFSFOEFSFS w IUUQTHJTUHJUIVCDPN LPCBFBGDBFBDEFGE &YBNQMFTPGDVTUPNSFOEFSFS

Slide 47

Slide 47 text

$POTPMFSFOEFSFS ReactConsole.render(
Hello World React Custom Renderer!
, () => console.log( colors.inverse('##### Update ######’) ) ); ReactConsole.render(
Hello World2 React
);

Slide 48

Slide 48 text

7PJDFSFOEFSFS ReactVoice.render([ Hello, React Fiber, ͜Μʹͪ͸ NodeֶԂ, ]); ???

Slide 49

Slide 49 text

'VUVSF

Slide 50

Slide 50 text

w 3FBDU'JCFSXJMMCFSFMFBTFEUIJTTVNNFSBTW XIJDI CFIBWFTBTTZODISPOPVTMZGPSCBDLXBSEDPNQBUJCJMJUZ w 3FBDU%0.VOTUBCMF@EFGFSSFE6QEBUFT MPX1SJPSJUZ w "TZODNPEFCZEFGBVMUJOW w 3FJNQMFNFOU3FBDU'JCFSCZBOZPUIFSMBOHVBHF w $ $ ʜ 'VUVSF

Slide 51

Slide 51 text

'VUVSF React Fiber (written by C or C++ or…) Native module Web Assembly React DOM React Native

Slide 52

Slide 52 text

3FBDU'JCFSJTBOJOGSBTUSVDUVSFUPBEENPSF GFBUVSFTFBTJMZ 3FTQPOTJWFOFTT1FSGPSNBODF

Slide 53

Slide 53 text

5IBOLZPV TQFBLFSEFDLDPNLPCB