$30 off During Our Annual Pro Sale. View Details »

๐Ÿ‡ช๐Ÿ‡ธ React Alicante 2022

๐Ÿ‡ช๐Ÿ‡ธ React Alicanteย 2022

โ„น๏ธ Inside Fiber: the in-depth overview you wanted a TLDR for

We'll have an in-depth overview of the important concepts behind reconciliation and React Fiber. Then, we'll explore how React uses this algorithm and go through a few magic words we hear a lot, like coroutines, continuations, generators, and algebraic effectsโ€”and see how they all relate to React.

Matheus Albuquerque

October 01, 2022
Tweet

More Decks by Matheus Albuquerque

Other Decks in Technology

Transcript

  1. ยกHola, React Alicante! โœ‹ ๐Ÿ‡ช๐Ÿ‡ธ INSIDE FIBER: THE IN-DEPTH OVERVIEW

    YOU WANTED A TLDR FOR โ€ข THE 28TH OF JUNE, 2022.
  2. MATHEUS ALBUQUERQUE INSIDE FIBER THE IN-DEPTH OVERVIEW YOU WANTED A

    TLDR FOR
  3. Iโ€™M MATHEUS ๐Ÿ™‹ โ† @YTHECOMBINATOR ON THE WEB โ† SR.

    SOFTWARE ENGINEER @MEDALLIA โ† MENTOR @TECHLABS
  4. Disclaimers INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR

    FOR
  5. #1 REACT SOURCE CODE IS CONSTANTLY CHANGING, AND SOME THOUGHTS

    ARE SPECULATIONS INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR FOR
  6. #2 INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR

    FOR ๐Ÿคฏ = FURTHER DISCUSSIONS AFTER THE SESSION
  7. A bit of context INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU

    WANTED A TLDR FOR
  8. INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR FOR

  9. CONTINUATIONS ALGEBRAIC EFFECTS COROUTINES FIBERS THREADS GENERATORS

  10. ALGEBRAIC EFFECTS COROUTINES FIBERS GENERATORS CONTINUATIONS THREADS

  11. Fiber(s) INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR

    FOR
  12. function add(x,y) { const result = x + y; return

    result; } add(2, 2) STACK FRAMES
  13. let frame: Frame = { return: frame, fn: add, parameters:

    [2, 2], localVariables: { result: 4, }, } STACK FRAMES
  14. let frame: Frame = { return: frame, fn: add, parameters:

    [2, 2], localVariables: { result: 4, }, } let fiber: Fiber = { return: fiber, component: Avatar, props: { id: 4 }, state: { isLoaded: true, }, } STACK FRAMES
  15. โ† FIBER ARCHITECTURE โ‡ข REACT-SPECIFIC IMPLEMENTATION OF A CALL-STACK-LIKE MODEL

    WHERE REACT HAS FULL CONTROL OF SCHEDULING WHAT SHOULD BE DONE โ† FIBER โ‡ข A STACK FRAME FOR A REACT COMPONENT FIBERS
  16. Fibers as Units of Work INSIDE FIBER: THE IN-DEPTH OVERVIEW

    YOU WANTED A TLDR FOR
  17. ONCE A TEMPLATE GOES THROUGH THE JSX COMPILER, YOU END

    UP WITH A BUNCH OF REACT ELEMENTS. DURING RECONCILIATION, DATA FROM EVERY REACT ELEMENT RETURNED FROM THE RENDER METHOD IS MERGED INTO THE TREE OF FIBER NODES. DEPENDING ON THE TYPE OF A REACT ELEMENT THE FRAMEWORK NEEDS TO PERFORM DIFFERENT ACTIVITIES. EACH ELEMENT IS CONVERTED INTO A FIBER NODE THAT DESCRIBES THE WORK THAT NEEDS TO BE DONE.
  18. ONCE A TEMPLATE GOES THROUGH THE JSX COMPILER, YOU END

    UP WITH A BUNCH OF REACT ELEMENTS. DURING RECONCILIATION, DATA FROM EVERY REACT ELEMENT RETURNED FROM THE RENDER METHOD IS MERGED INTO THE TREE OF FIBER NODES. DEPENDING ON THE TYPE OF A REACT ELEMENT THE FRAMEWORK NEEDS TO PERFORM DIFFERENT ACTIVITIES. EACH ELEMENT IS CONVERTED INTO A FIBER NODE THAT DESCRIBES THE WORK THAT NEEDS TO BE DONE.
  19. ONCE A TEMPLATE GOES THROUGH THE JSX COMPILER, YOU END

    UP WITH A BUNCH OF REACT ELEMENTS. DURING RECONCILIATION, DATA FROM EVERY REACT ELEMENT RETURNED FROM THE RENDER METHOD IS MERGED INTO THE TREE OF FIBER NODES. DEPENDING ON THE TYPE OF A REACT ELEMENT THE FRAMEWORK NEEDS TO PERFORM DIFFERENT ACTIVITIES. EACH ELEMENT IS CONVERTED INTO A FIBER NODE THAT DESCRIBES THE WORK THAT NEEDS TO BE DONE.
  20. ONCE A TEMPLATE GOES THROUGH THE JSX COMPILER, YOU END

    UP WITH A BUNCH OF REACT ELEMENTS. DURING RECONCILIATION, DATA FROM EVERY REACT ELEMENT RETURNED FROM THE RENDER METHOD IS MERGED INTO THE TREE OF FIBER NODES. DEPENDING ON THE TYPE OF A REACT ELEMENT THE FRAMEWORK NEEDS TO PERFORM DIFFERENT ACTIVITIES. EACH ELEMENT IS CONVERTED INTO A FIBER NODE THAT DESCRIBES THE WORK THAT NEEDS TO BE DONE.
  21. ONCE A TEMPLATE GOES THROUGH THE JSX COMPILER, YOU END

    UP WITH A BUNCH OF REACT ELEMENTS. DURING RECONCILIATION, DATA FROM EVERY REACT ELEMENT RETURNED FROM THE RENDER METHOD IS MERGED INTO THE TREE OF FIBER NODES. DEPENDING ON THE TYPE OF A REACT ELEMENT THE FRAMEWORK NEEDS TO PERFORM DIFFERENT ACTIVITIES. EACH ELEMENT IS CONVERTED INTO A FIBER NODE THAT DESCRIBES THE WORK THAT NEEDS TO BE DONE. A UNIT OF WORK.
  22. ONCE A TEMPLATE GOES THROUGH THE JSX COMPILER, YOU END

    UP WITH A BUNCH OF REACT ELEMENTS. DURING RECONCILIATION, DATA FROM EVERY REACT ELEMENT RETURNED FROM THE RENDER METHOD IS MERGED INTO THE TREE OF FIBER NODES. DEPENDING ON THE TYPE OF A REACT ELEMENT THE FRAMEWORK NEEDS TO PERFORM DIFFERENT ACTIVITIES. EACH ELEMENT IS CONVERTED INTO A FIBER NODE THAT DESCRIBES THE WORK THAT NEEDS TO BE DONE. A UNIT OF WORK. AND THAT MAKES IT A CONVENIENT WAY TO TRACK, SCHEDULE, PAUSE AND ABORT THE WORK.
  23. Visualizing Units of Work INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU

    WANTED A TLDR FOR
  24. #EXPERIMENT ๐Ÿ’ป #1 Inspecting Elements

  25. None
  26. None
  27. let fiberNode = fiberRoot.current; let fibersMap = new Map(); while

    (fiberNode) { if (fiberNode.stateNode ! = = null) { fibersMap.set(fiberNode.stateNode, fiberNode); } if (fiberNode.child === null) { while (fiberNode ! = = null & & fiberNode.sibling === null) { fiberNode = fiberNode.return; } fiberNode = fiberNode?.sibling; continue; } fiberNode = fiberNode.child; }
  28. let fiberNode = fiberRoot.current; let fibersMap = new Map(); while

    (fiberNode) { if (fiberNode.stateNode ! = = null) { fibersMap.set(fiberNode.stateNode, fiberNode); } if (fiberNode.child === null) { while (fiberNode ! = = null & & fiberNode.sibling === null) { fiberNode = fiberNode.return; } fiberNode = fiberNode?.sibling; continue; } fiberNode = fiberNode.child; } ๐Ÿคฏ
  29. None
  30. INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR FOR

  31. INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR FOR

  32. Manipulating Units of Work INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU

    WANTED A TLDR FOR
  33. #QUESTION ๐Ÿค” Have you ever heard about homoiconicity?

  34. (let [x 1] (inc x)) ; = > 2 HOMOICONICITY

  35. (let [x 1] (inc x)) ; = > 2 HOMOICONICITY

    PERFORMS A TEMPORARY BINDING (BINDS X TO THE VALUE 1)
  36. INCREMENTS X TO GIVE THE RETURN VALUE OF 2 (let

    [x 1] (inc x)) ; = > 2 HOMOICONICITY
  37. IT CAN BE THOUGHT OF AS A LIST WITH THREE

    ELEMENTS โ† A SYMBOL NAMED LET โ† A VECTOR WITH TWO ELEMENTS โ† A LIST WITH TWO ELEMENTS HOMOICONICITY
  38. IT CAN BE THOUGHT OF AS A LIST WITH THREE

    ELEMENTS โ† A SYMBOL NAMED LET โ† A VECTOR WITH TWO ELEMENTS โ† A LIST WITH TWO ELEMENTS HOMOICONICITY A SYMBOL (X) AND AN INTEGER A SYMBOL (INC) AND A SYMBOL (X)
  39. ๐Ÿคฏ #QUOTE ๐Ÿค” โ€œโ€ฆHomoiconicity is a property of some programming

    languages in which the code used to express a program is written using the data structures of that language.โ€
  40. โ† REACT ELEMENTS ARE JUST DATA โ† JUST LIKE IN

    LISP, REACT COMPONENTS CAN MANIPULATE THEIR CHILDREN AND RETURN COMPLETELY DIFFERENT THINGS HOMOICONICITY
  41. #EXPERIMENT ๐Ÿ’ป #2 Pattern Matching in React

  42. PATTERN MATCHING

  43. / / . . . export function isWhen<Shape extends {}>(

    child: ElementWithMetadataUnion<Shape> ): child is ElementWithMetadata<WhenProps<Shape > > { return child.element.type === When; } / / . . . export function nodesToElementWithMetadata<Shape extends {}>( children: ReactNode ) { return Children.toArray(children).map((element, idx) = > ({ element: element, position: idx, })) as Array<ElementWithMetadata<Shape > > ; } / / . . .
  44. const supportsSensor = () = > Boolean(window.AmbientLightSensor); const AmbientLight =

    React.lazy(() = > import("./AmbientLight")); const Fallback = React.lazy(() = > import("./Fallback")); export default function MyComponent() { const { Match, When, Otherwise } = usePatternMatch(); return ( <Suspense fallback="Loading"> <Match> <When predicate={supportsSensor}> <AmbientLight /> </When> <Otherwise> <Fallback /> </Otherwise> </Match> </Suspense> ); } PATTERN MATCHING
  45. const supportsSensor = () = > Boolean(window.AmbientLightSensor); const AmbientLight =

    React.lazy(() = > import("./AmbientLight")); const Fallback = React.lazy(() = > import("./Fallback")); export default function MyComponent() { const { Match, When, Otherwise } = usePatternMatch(); return ( <Suspense fallback="Loading"> <Match> <When predicate={supportsSensor}> <AmbientLight /> </When> <Otherwise> <Fallback /> </Otherwise> </Match> </Suspense> ); } PATTERN MATCHING + REACT.SUSPENSE + REACT.LAZY() = USERS DOWNLOAD ONLY THE COMPONENT BUNDLE THAT MATCHES
  46. const supportsSensor + REACT.SUSPENSE + REACT.LAZY() = USERS DOWNLOAD ONLY

    THE COMPONENT BUNDLE THAT MATCHES MANIPULATING BASED ON ELEMENTS DATA.
  47. INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR FOR

  48. Fibers out there INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED

    A TLDR FOR
  49. โ† A FIBER IS A GENERIC MODEL OF EXECUTION WHERE

    EACH UNIT WORKS TOGETHER COOPERATIVELY โ† FIBERS ARE A COMMON RESOURCE IN SOME OPERATING SYSTEMS (E.G. WINDOWS) AND IN SOME PROGRAMMING LANGUAGES (E.G. OCAML) FIBERS OUT THERE
  50. Coroutines INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR

    FOR
  51. None
  52. #1 A GENERATOR (PRODUCER) THAT CAN ALSO CONSUME VALUES. INSIDE

    FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR FOR
  53. #1 INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR

    FOR โ† JAVASCRIPT GENERATORS CAN CONSUME VALUES โ† BY THIS DEFINITION, THEY ARE COROUTINES A GENERATOR (PRODUCER) THAT CAN ALSO CONSUME VALUES.
  54. #2 A GENERATOR THAT CAN RESOLVE ASYNCHRONOUS VALUES, LIKE ASYNC/AWAIT.

    INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR FOR
  55. #2 INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR

    FOR โ† THIS IS THE MOST COMMON MEANING OF โ€œCOROUTINEโ€ IN THE JAVASCRIPT WORLD โ† WE HAD CO AND BLUEBIRD, WHICH HAD ASYNC/AWAIT IMPLEMENTATIONS BASED ON GENERATORS VALUES, LIKE ASYNC/AWAIT.
  56. #3 A GENERATOR THAT CAN YIELD WITH A STACKFUL CONTINUATION

    INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR FOR
  57. #3 INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR

    FOR โ† "DEEP AWAIT" โ† e.g. WITH SUSPENSE, WE CAN PAUSE RECONCILIATION AT ANY DEPTH A GENERATOR THAT CAN YIELD WITH A STACKFUL CONTINUATION
  58. Fibers CONTROL IS PASSED TO A SCHEDULER WHICH DETERMINES WHAT

    TO RUN NEXT โ† = CONTROLLED AT THE LEVEL OF THE OPERATING SYSTEM OR FRAMEWORK โ† E.G. NODE.JS EVENT LOOP
  59. Coroutines CONTROL IS PASSED TO THE CALLER AND HANDLED BY

    APPLICATION CODE Fibers CONTROL IS PASSED TO A SCHEDULER WHICH DETERMINES WHAT TO RUN NEXT
  60. Coroutines & React INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED

    A TLDR FOR
  61. COROUTINES APPEARED WHEN WORK ON FIBER WAS FIRST GOING AS

    A SPECIFIC COMPONENT TYPE. THE IDEA BEHIND COROUTINESโ€Šโ€”โ€ŠAS OPPOSED TO FIBERSโ€Šโ€”โ€ŠWAS TO GIVE COMPONENTS EXPLICIT CONTROL OVER YIELDING AND RESUMPTION.
  62. INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR FOR

  63. COROUTINES & REACT โ† COROUTINES PER SI IN REACT NO

    LONGER EXIST. โ† IT WILL BE FASCINATING TO SEE WHAT FORM COROUTINES TAKE WHEN THEY RETURN TO REACT FIBER.
  64. Coroutines & Concurrent React INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU

    WANTED A TLDR FOR
  65. INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR FOR

  66. INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR FOR

  67. function resourcefulOperation(value: number) { let newValue = String(value); for (let

    i = 0; i < 1000000; i++) { newValue = `${value} + ${i} = ${value + i}`; } return newValue; } function ResourcefulComponent(props: { value: number }) { const { value } = props; const result = resourcefulOperation(value); return <p>{result}</p>; }
  68. #EXPERIMENT ๐Ÿ’ป #3 Building a coroutines-based scheduler

  69. INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR FOR

  70. None
  71. function resourcefulOperation(value: number) { let newValue = String(value); for (let

    i = 0; i < 1000000; i++) { newValue = `${value} + ${i} = ${value + i}`; } return newValue; } function ResourcefulComponent(props: { value: number }) { const { value } = props; const result = resourcefulOperation(value); return <p>{result}</p>; }
  72. function* resourcefulOperation(value: number) { let newValue = String(value); while (true)

    { yield; for (let i = 0; i < 1000000; i++) { newValue = `${value} + ${i} = ${value + i}`; } return newValue; } } const initialValue = 0; const scheduler = new Scheduler(resourcefulOperation, initialValue); function ResourcefulComponent(props: { value: number }) { const { value } = props; const result = scheduler.performUnitOfWork(value); return <p>{result}</p>; }
  73. function* resourcefulOperation(value: number) { let newValue = String(value); while (true)

    { yield; for (let i = 0; i < 1000000; i++) { newValue = `${value} + ${i} = ${value + i}`; } return newValue; } } const initialValue = 0; const scheduler = new Scheduler(resourcefulOperation, initialValue); function ResourcefulComponent(props: { value: number }) { const { value } = props; const result = scheduler.performUnitOfWork(value); return <p>{result}</p>; } PROMOTED TO A GENERATOR YIELDING EXECUTION DOING CONCURRENT TASKS
  74. DEEP DIVING ON CONCURRENT REACT

  75. enum SchedulerState { IDLE = "IDLE", PENDING = "PENDING", DONE

    = "DONE", } class Scheduler<T> { state: SchedulerState; result: T; worker: (data: T) = > Generator; iterator: Generator; constructor(worker: (data: T) = > Generator, initialResult: T) { this.state = SchedulerState.IDLE; this.worker = worker; this.result = initialResult; } performUnitOfWork(data: T) { switch (this.state) { case "IDLE": this.state = SchedulerState.PENDING; this.iterator = this.worker(data); throw Promise.resolve(); case "PENDING": const { value, done } = this.iterator.next(); if (done) { this.result = value; this.state = SchedulerState.DONE; return value; } throw Promise.resolve(); case "DONE": this.state = SchedulerState.IDLE; return this.result; } } }
  76. performUnitOfWork(data: T) { switch (this.state) { case "IDLE": this.state =

    SchedulerState.PENDING; this.iterator = this.worker(data); throw Promise.resolve(); case "PENDING": const { value, done } = this.iterator.next(); if (done) { this.result = value; this.state = SchedulerState.DONE; return value; } throw Promise.resolve(); case "DONE": this.state = SchedulerState.IDLE; return this.result; } }
  77. DID WE JUST useTransitionโ€™ED? ๐Ÿค”

  78. function resourcefulOperation(value: number) { let newValue = String(value); for (let

    i = 0; i < 1000000; i++) { newValue = `${value} + ${i} = ${value + i}`; } return newValue; } function ResourcefulComponent(props: { value: number }) { const { value } = props; const result = resourcefulOperation(value); return <p>{result}</p>; }
  79. function resourcefulOperation(value: number) { let newValue = String(value); for (let

    i = 0; i < 1000000; i++) { newValue = `${value} + ${i} = ${value + i}`; } return newValue; } function ResourcefulComponent(props: { value: number }) { const [_, startTransition] = useTransition(); const [result, setResult] = useState(""); useEffect(() = > { startTransition(() = > { const newResult = resourcefulOperation(props.value); setResult(newResult); }); }, [props.value]); return <p>{result}</p>; }
  80. YES, WE DID ๐Ÿค“ WITH OUR OWN, COROUTINES-BASED, SCHEDULER

  81. โ† A COOPERATIVE MULTITASKING MODEL โ† A SINGLE INTERRUPTIBLE RENDERING

    THREAD โ† RENDERING CAN BE INTERLEAVED WITH OTHER MAIN THREAD TASKS AND OTHER REACT RENDERS โ† AN UPDATE CAN HAPPEN IN THE BACKGROUND WITHOUT BLOCKING THE RESPONSE TO NEW INPUT COROUTINES & SCHEDULING
  82. โ† โ†“ ORIGINAL RENDER TASK USER INPUT โ†’ โ†‘ HIGHER

    PRIORITY RENDER TASK โ†“ RESUME ORIGINAL RENDER TASK
  83. โ† IT YIELDS EXECUTION IS BACK TO THE MAIN THREAD

    EVERY 5MS โ† IT'S SMALLER THAN A SINGLE FRAME EVEN ON 120FPS, SO IT WON'T BLOCK ANIMATIONS โ† IN PRACTICE, RENDERING IS INTERRUPTIBLE COROUTINES & SCHEDULING
  84. Coroutines out there INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED

    A TLDR FOR
  85. โ† ASYNCHRONY IN JAVASCRIPT IS CONTAGIOUS โ† IF ANY FUNCTION

    IS ASYNC, THEN EVERYTHING THAT CALLS IT MUST ALSO BE ASYNCโ€ฆ โ† โ€ฆAND SO ON UNTIL THE ENTIRE PROGRAM IS ASYNCHRONOUS ๐Ÿคท ASYNCHRONY & JS
  86. โ† ASYNCHRONY IN JAVASCRIPT ISNโ€™T FREE โ† EVERY ASYNCHRONOUS FUNCTION

    CALL HAS TO: โ† ALLOCATE CALLBACKS & STORE THEM SOMEWHERE โ† TAKE A TRIP BACK TO THE EVENT LOOP BEFORE INVOKING THOSE CALLBACKS ASYNCHRONY & JS
  87. None
  88. โ† ITS API HAS TWO MAIN FUNCTIONS FOR COMPILING SASS

    FILES: ONE SYNC AND ONE ASYNC โ† THE ASYNC ONE BECAME WIDELY USED IN PRACTICE BECAUSE IT ENABLED ASYNC PLUGINS (E.G. WEBPACKโ€™S SASS-LOADER) ASYNCHRONY & SASS
  89. โ† FOR NODE SASS, THE PERFORMANCE DIFFERENCE WAS NEGLIGIBLE, BECAUSE

    IT WAS BUILT ON C++ โ† HOWEVER, DART SASS RUNS AS PURE JAVASCRIPT, WHICH MAKES IT SUBJECT TO JAVASCRIPTโ€™S ASYNC RULES ASYNCHRONY & SASS
  90. โ† THE ASYNC VERSION IN DART SASS WAS 2-3X SLOWER

    THAN THE SYNC ONE โ† THEY STARTED USING NODE-FIBERS TO IMPLEMENT THE ASYNC API USING THE FAST, SYNC, CODE ASYNCHRONY & SASS
  91. INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR FOR

  92. None
  93. Continuations INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR

    FOR
  94. CONTINUATIONS

  95. CONTINUATIONS โ† A CONTINUATION IS A CONTROL FLOW PRIMITIVE. โ†

    ITโ€™S AN ABSTRACTION THAT REPRESENTS THE REMAINING STEPS IN A COMPUTATION.
  96. INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR FOR

  97. function performWork(deadline) { while (tasks.length > 0) { const task

    = tasks.shift(); doTask(task); if ( tasks.length > 0 & & !deadline.didTimeout & & deadline.timeRemaining() < = 0 ) { return performWork; } } } scheduleWork(performWork); CONTINUATIONS IN REACT
  98. โ† IT HANDLES A QUEUE OF TASKS IN A WHILE

    LOOP โ† IF THERE ARE STILL TASKS ON THE QUEUE, IT RETURNS performWork AND SCHEDULE IT FOR RESUMPTION AT SOME LATER TIME โ† IN THIS CONTEXT, IT REPRESENTS THE CONTINUATION OF A QUEUE OF TASKS CONTINUATIONS IN REACT
  99. CONTINUATIONS ON THE WEB

  100. CONTINUATIONS ON THE WEB async function doWork() { while (true)

    { let hasMoreWork = doSomeWork(); if (!hasMoreWork) { return; } if (!navigator.scheduling.isInputPending()) { continue; } await scheduler.yield(); } } ๐Ÿคฏ
  101. INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR FOR

  102. Effect Handlers INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A

    TLDR FOR
  103. โ† EFFECTS ASK THE CALLING ENVIRONMENT TO HANDLE A PARTICULAR

    TASK โ† WHEN AN EFFECT IS USED, THE NEAREST EFFECT HANDLER IS CALLED, WHICH ALLOWS YOU TO RUN CODE IN RESPONSE TO THE EFFECT AND RETURN SOME VALUE EFFECT HANDLERS ๐Ÿคฏ
  104. INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR FOR

  105. function getName(user) { let name = user.name; if (name ===

    null) { name = perform 'ask_name'; } return name; } const arya = { name: null, friendNames: [] }; const gendry = { name: 'Gendry', friendNames: [] }; try { getName(arya); } handle (effect) { if (effect === 'ask_name') { resume with 'Arya Stark'; } }
  106. function getName(user) { let name = user.name; if (name ===

    null) { name = perform 'ask_name'; } return name; } const arya = { name: null, friendNames: [] }; const gendry = { name: 'Gendry', friendNames: [] }; try { getName(arya); } handle (effect) { if (effect === 'ask_name') { resume with 'Arya Stark'; } }
  107. function getName(user) { let name = user.name; if (name ===

    null) { name = perform 'ask_name'; } return name; } const arya = { name: null, friendNames: [] }; const gendry = { name: 'Gendry', friendNames: [] }; try { getName(arya); } handle (effect) { if (effect === 'ask_name') { resume with 'Arya Stark'; } } THROW โ†’ PERFORM CATCH โ†’ HANDLE LETS US JUMP BACK TO WHERE WE PERFORMED THE EFFECT
  108. Effect handlers in React INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU

    WANTED A TLDR FOR
  109. #1 INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR

    FOR LAYOUT ALGORITHM
  110. THE REACT TEAM APPARENTLY SPENT SOME TIME EXPERIMENTING WITH EFFECT-

    HANDLER CONTROL STRUCTURES FOR MANAGING LAYOUT
  111. INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR FOR

  112. #2 INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR

    FOR CONTEXT API DRAFTS
  113. THEYโ€™VE ALSO REMODELED THE CONTEXT API USING ALGEBRAIC EFFECTS

  114. INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR FOR

  115. #3 INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR

    FOR SIDE EFFECTS WITHIN A COMPONENT
  116. INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR FOR

  117. function ThemeBorderColorRequest() { } function FancyBox(children) { const color =

    raise new ThemeBorderColorRequest(); return { borderWidth: '1px', borderColor: color, children: children }; } function BlueTheme(children) { return try { children(); } catch effect ThemeBorderColorRequest - > [, continuation] { continuation('blue'); } } function App(data) { return BlueTheme( FancyUserList.bind(null, data.users) ); }
  118. function ThemeBorderColorRequest() { } function FancyBox(children) { const color =

    raise new ThemeBorderColorRequest(); return { borderWidth: '1px', borderColor: color, children: children }; } function BlueTheme(children) { return try { children(); } catch effect ThemeBorderColorRequest - > [, continuation] { continuation('blue'); } } function App(data) { return BlueTheme( FancyUserList.bind(null, data.users) ); } THROW โ†’ RAISE CATCH โ†’ CATCH EFFECT
  119. #4 INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR

    FOR HOOKS API DRAFTS
  120. INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR FOR

  121. SEBASTIAN POINTS THAT โ€œCONCEPTUALLY, HOOKS ARE ALGEBRAIC EFFECTSโ€.

  122. #5 INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR

    FOR SUSPENSE INTERNALS
  123. #QUESTION ๐Ÿค” Have you ever built any suspense- ready API?

  124. INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR FOR

  125. A COMPONENT IS ABLE TO SUSPEND THE FIBER IT IS

    RUNNING IN BY THROWING A PROMISE, WHICH IS CAUGHT AND HANDLED BY THE FRAMEWORK.
  126. A COMPONENT IS ABLE TO SUSPEND THE FIBER IT IS

    RUNNING IN BY THROWING A PROMISE, WHICH IS CAUGHT AND HANDLED BY THE FRAMEWORK. THROW โ†’ HANDLE โ†’ RESUME PATTERN.
  127. INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR FOR

    Closing Notes
  128. #1 REACT FIBER WAS A REWRITE OF REACT FOCUSED ON

    GIVING MORE LOW-LEVEL CONTROL OVER PROGRAM EXECUTION INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR FOR
  129. #1 INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR

    FOR โ† FIBERS AS A LOW-LEVEL COOPERATIVE WAY TO MODEL EXECUTION โ† ALGEBRAIC EFFECTS AS A WAY TO HANDLE EFFECTS WHERE THESE AND THEIR BEHAVIOR ARE INDEPENDENT EXECUTION
  130. #2 INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR

    FOR REACT TRIES TO ADDRESS THE LACK OF SOME JAVASCRIPT FEATURES/ LANGUAGE-LEVEL RESOURCES BY IMPLEMENTING SOME ALTERNATIVE SOLUTIONS TO ACHIEVE SIMILAR BEHAVIORS E.G. EFFECT HANDLERS & CONTINUATIONS
  131. #3 INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR

    FOR UNDERSTANDING THESE INTERNALS AND THEIR RATIONALES HELPS US IMPLEMENT OUR OWN ABSTRACTIONS E.G. THE COROUTINES-BASED SCHEDULER & THE PATTERN MATCHING COMPONENTS
  132. None
  133. #4 THE FACT WE'RE DISCUSSING ALL OF THESE TOPICS SHOWS

    THAT REACT ACTS AS A DEMOCRATIC AGENT FOR THIS KIND OF KNOWLEDGE IN THE FRONT-END WORLD INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR FOR
  134. None
  135. THIS IS THE EIGHT-YEARS-AGO-ME GIVING A TALK ABOUT IONIC AT

    AN IOS DEVELOPERS MEETUP TELLING THEM THAT ANGULAR WOULD BE THE FUTURE.
  136. #5 INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR

    FOR DONโ€™T ALWAYS TRUST ALL OF MY SPECULATIONS/FUTURE PREDICTIONS ๐Ÿคท
  137. Weโ€™re hiring! ๐Ÿ—บ Mostly inโ€ฆ ๐Ÿ‡บ๐Ÿ‡ธ๐Ÿ‡ฒ๐Ÿ‡ฝ๐Ÿ‡ฆ๐Ÿ‡ท๐Ÿ‡บ๐Ÿ‡พ๐Ÿ‡ช๐Ÿ‡ธ๐Ÿ‡จ๐Ÿ‡ฟ๐Ÿ‡ฎ๐Ÿ‡ฑ๐Ÿ‡ฎ๐Ÿ‡ณ

  138. ๐Ÿค ๐Ÿ‡ช๐Ÿ‡ธ ๐Ÿค—

  139. INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR FOR

  140. INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR FOR

  141. None
  142. MATHEUS ALBUQUERQUE THATโ€™S ALL, FOLKS! THANKS! QUESTIONS?