Capability of React Fiber

45daf58c77e9dbbab5a1c8a5afc7ac5c?s=47 koba04
June 27, 2017

Capability of React Fiber

45daf58c77e9dbbab5a1c8a5afc7ac5c?s=128

koba04

June 27, 2017
Tweet

Transcript

  1. $BQBCJMJUZPG3FBDU'JCFS /PEFֶԂ   !LPCB

  2. !LPCB

  3. $POUSJCVUJOH3FBDU'JCFS

  4. $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 :
  5. http://blog.koba04.com/post/2017/04/25/a-state-of-react-fiber/

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

  7. 5IFpSTU13PG3FBDU'JCFS

  8. $BWFBU

  9. w 3FBDU'JCFS`TBTZODISPOPVTXPSLJTTUJMMJOVOEFS EFWFMPQNFOU w 5IFJNQMFNFOUBUJPOIBTCFFODIBOHJOH w 5IFDIBOHFTBSFSFMBUFEUPBTZODISPOPVTXPSL FOBCMFEJOW w 4PNFGFBUVSFT*`NHPOOBUPJOUSPEVDFJOUIJT

    QSFTFOUBUJPOBSFOPUFOBCMFEJOW $BWFBU
  10. None
  11. "SDIJUFDUVSFPG3FBDU

  12. <div /> Component + JSX Reconciler Renderer <App /> <Text

    /> Fiber Stack DOM Native View Canvas
  13. 8IBUJT3FDPODJMJBUJPO

  14. w #VJME3FBDU&MFNFOUUSFFT w .PVOU 6QEBUF 6ONPVOUDPNQPOFOUT w $BMMJOHMJGFDZDMFNFUIPET w $PNQVUFDIBOHFT

    w 5FMMBSFOEFSFSDIBOHFTʜ w *UXBTDBMMFE7JSUVBM%0. 3FDPODJMJBUJPO
  15. 8IBUJT3FBDU'JCFS

  16. w 3FBDU'JCFSJTBOFXSFDPODJMJBUJPOBMHPSJUIN w &OBCMFTDIFEVMJOHVQEBUFT w *U`TQPTTJCMFUPSFUVSOBOBSSBZ TUSJOHTGSPNSFOEFS NFUIPEEJSFDUMZ w 1PSUBMT

    &SSPSCPVOEBSJFT $PSPVUJOF$PNQPOFOUʜ w .BLFT6*SFTQPOTJWFOFTT w /PUGPSTQFFEUIBUCFODINBSLTNFBTVSF 3FBDU'JCFS
  17. 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, };
  18. 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
  19. 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, };
  20. 8IZJT3FBDU'JCFSOFDFTTBSZ

  21. w $VSSFOUJNQMFNFOUBUJPOJTUSBWFSTJOH3FBDU&MFNFOUUSFF SFDVSTJWFMZBOETZODISPOPVTMZ 8IZJT3FBDU'JCFSOFDFTTBSZ <App /> <div /> <Button />

    <List /> <Item /> <Item /> <Item /> Recursive & Synchronously ↓ Blocking UI & Drop frames mount mount mount
  22. 8IBUJT4DIFEVMJOH

  23. w 5JNFCBTFTDIFEVMJOH w 4DIFEVMJOHXJUISFRVFTU*EMF$BMMCBDL w 1SJPSJUZCBTFTDIFEVMJOH w )JHIQSJPSJUZVQEBUFTDBOJOUFSSVQUUPMPXQSJPSJUZ VQEBUFT w

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

    w *O$PNNJU8PSL w DPNQPOFOU%JE.PVOU DPNQPOFOU%JE6QEBUF  DPNQPOFOU8JMM6ONPVOU -JGFDZDMFNFUIPET
  26. 1IBTFT Fiber Fiber Fiber Fiber CommitWork Beginʙ CompleteWork Beginʙ CompleteWork

    … SideEffect SideEffect SideEffect Host (DOM)
  27. 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 };
  28. 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/)
  29. '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)
  30. 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!
  31. *OUFSSVQUBIJHIQSJPSJUZVQEBUF FiberA FiberB FiberA FiberC Commit Low Priority High Priority

    Commit FiberA FiberB FiberC Low Priority Reuse Interrupted Resume
  32. %FNP https://koba04.github.io/react-fiber-resources/examples/

  33. 4UBDLSFDPODJMFS

  34. 'JCFSSFDPODJMFSXJUITZODQSJPSJUZ

  35. 'JCFSSFDPODJMFSXJUIMPXQSJPSJUZ BeginʙCompleteWork CommitWork

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

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

  38. 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);
  39. 0⒎4DSFFO1SJPSJUZ Low priority Offscreen priority Commit Work

  40. 8IBUBCPVU443

  41. w "OFXTFSWFSSFOEFSFSJTJOEFQFOEFOUSFOEFSFS XIJDI EPFTO`UVTF'JCFSSFDPODJMFS w IUUQTHJUIVCDPNGBDFCPPLSFBDUCMPCNBTUFSTSD SFOEFSFSTTIBSFETFSWFS3FBDU1BSUJBM3FOEFSFSKT w 5IFTFSWFSSFOEFSFSTVQQPSUTTUSFBNJOH"1* 8IBUBCPVU443

    import ReactDOMNodeStream from ‘react-dom/node-stream’; ReactDOMNodeStream.renderToStream(<App />); // ReactDOMNodeStream.renderToStaticStream(<App />);
  42. 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; }
  43. )PXEP*CVJMEBDVTUPNSFOEFSFS

  44. 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
  45. 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
  46. w $POTPMFSFOEFSFS w IUUQTHJTUHJUIVCDPN LPCBDCECEGBFDB w 7PJDFSFOEFSFS w IUUQTHJTUHJUIVCDPN LPCBFBGDBFBDEFGE

    &YBNQMFTPGDVTUPNSFOEFSFS
  47. $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> );
  48. 7PJDFSFOEFSFS ReactVoice.render([ <alex key={1}>Hello</alex>, <victoria key={2}>React Fiber</victoria>, <kyoko key={3}>͜Μʹͪ͸ NodeֶԂ</kyoko>,

    ]); ???
  49. 'VUVSF

  50. w 3FBDU'JCFSXJMMCFSFMFBTFEUIJTTVNNFSBTW XIJDI CFIBWFTBTTZODISPOPVTMZGPSCBDLXBSEDPNQBUJCJMJUZ w 3FBDU%0.VOTUBCMF@EFGFSSFE6QEBUFT MPX1SJPSJUZ  w "TZODNPEFCZEFGBVMUJOW

    w 3FJNQMFNFOU3FBDU'JCFSCZBOZPUIFSMBOHVBHF  w $ $ ʜ 'VUVSF
  51. 'VUVSF React Fiber (written by C or C++ or…) Native

    module Web Assembly React DOM React Native
  52. 3FBDU'JCFSJTBOJOGSBTUSVDUVSFUPBEENPSF GFBUVSFTFBTJMZ 3FTQPOTJWFOFTT1FSGPSNBODF

  53. 5IBOLZPV TQFBLFSEFDLDPNLPCB