Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Capability of React Fiber

Avatar for koba04 koba04
June 27, 2017

Capability of React Fiber

Avatar for koba04

koba04

June 27, 2017
Tweet

More Decks by koba04

Other Decks in Programming

Transcript

  1. $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 :
  2. <div /> Component + JSX Reconciler Renderer <App /> <Text

    /> Fiber Stack DOM Native View Canvas
  3. w #VJME3FBDU&MFNFOUUSFFT w .PVOU 6QEBUF 6ONPVOUDPNQPOFOUT w $BMMJOHMJGFDZDMFNFUIPET w $PNQVUFDIBOHFT

    w 5FMMBSFOEFSFSDIBOHFTʜ w *UXBTDBMMFE7JSUVBM%0. 3FDPODJMJBUJPO
  4. w 3FBDU'JCFSJTBOFXSFDPODJMJBUJPOBMHPSJUIN w &OBCMFTDIFEVMJOHVQEBUFT w *U`TQPTTJCMFUPSFUVSOBOBSSBZ TUSJOHTGSPNSFOEFS NFUIPEEJSFDUMZ w 1PSUBMT

    &SSPSCPVOEBSJFT $PSPVUJOF$PNQPOFOUʜ w .BLFT6*SFTQPOTJWFOFTT w /PUGPSTQFFEUIBUCFODINBSLTNFBTVSF 3FBDU'JCFS
  5. 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, };
  6. 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
  7. 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, };
  8. w $VSSFOUJNQMFNFOUBUJPOJTUSBWFSTJOH3FBDU&MFNFOUUSFF SFDVSTJWFMZBOETZODISPOPVTMZ 8IZJT3FBDU'JCFSOFDFTTBSZ <App /> <div /> <Button />

    <List /> <Item /> <Item /> <Item /> Recursive & Synchronously ↓ Blocking UI & Drop frames mount mount mount
  9. w 5JNFCBTFTDIFEVMJOH w 4DIFEVMJOHXJUISFRVFTU*EMF$BMMCBDL w 1SJPSJUZCBTFTDIFEVMJOH w )JHIQSJPSJUZVQEBUFTDBOJOUFSSVQUUPMPXQSJPSJUZ VQEBUFT w

    3FBDU'JCFSJTBCMFUPSFTVNFJOUFSSVQUFEVQEBUFTMBUFS w 1SJPSJUJFTBSF4ZOD 5BTL )JHI -PXBOE0⒎4DSFFO 8IBUJT4DIFEVMJOH
  10. 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
  11. w *O#FHJO8PSL w DPNQPOFOU8JMM.PVOU DPNQPOFOU8JMM3FDFJWF1SPQT  TIPVME$PNQPOFOU6QEBUF DPNQPOFOU8JMM6QEBUF w 5IFTFNBZCFDBMMFETFWFSBMUJNFT

    w *O$PNNJU8PSL w DPNQPOFOU%JE.PVOU DPNQPOFOU%JE6QEBUF  DPNQPOFOU8JMM6ONPVOU -JGFDZDMFNFUIPET
  12. 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 };
  13. 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/)
  14. '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)
  15. 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 Stop and resume anywhere!
  16. *OUFSSVQUBIJHIQSJPSJUZVQEBUF FiberA FiberB FiberA FiberC Commit Low Priority High Priority

    Commit FiberA FiberB FiberC Low Priority Reuse Interrupted Resume
  17. 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);
  18. 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; }
  19. 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
  20. 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
  21. $POTPMFSFOEFSFS 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> );
  22. 'VUVSF React Fiber (written by C or C++ or…) Native

    module Web Assembly React DOM React Native