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

Capability of React Fiber

koba04
June 27, 2017

Capability of React Fiber

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