Matheus Albuquerque
September 08, 2022
20

# ๐ฉ๐ช React Day Berlin Meetupย 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

September 08, 2022

## Transcript

1. ### Hello, React Berlin ๐ ๐ฉ๐ช ๐ INSIDE FIBER: THE IN-DEPTH

OVERVIEW YOU WANTED A TLDR FOR โข THE 8TH OF SEPTEMBER, 2022.

TLDR FOR
3. ### IโM MATHEUS ๐ โ @YTHECOMBINATOR ON THE WEB โ SR.

SOFTWARE ENGINEER @ MEDALLIA โ MENTOR @ TECHLABS BERLIN

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

ARE SPECULATIVE

A TLDR
7. ### 2. MAYBE THIS TALK WONโT BE 100% WHAT YOUโD CALL

A TLDR ๐ป= HUGE CONTENT PAYLOAD / DESERVES FURTHER DISCUSSIONS AFTER THE SESSION
8. ### A bit of context INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU

WANTED A TLDR FOR

FOR

FOR

15. ### let frame: Frame = { return: frame, fn: add, parameters:

[2, 2], localVariables: { result: 4, }, }
16. ### 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, }, }
17. ### โ 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
18. ### Fibers as Units of Work INSIDE FIBER: THE IN-DEPTH OVERVIEW

YOU WANTED A TLDR FOR
19. ### 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. ONCE A TEMPLATE GOES THROUGH THE JSX COMPILER, YOU END UP WITH A BUNCH OF REACT ELEMENTS.
20. ### 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. ONCE A TEMPLATE GOES THROUGH THE JSX COMPILER, YOU END UP WITH A BUNCH OF REACT ELEMENTS.
21. ### 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. 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.
22. ### EACH ELEMENT IS CONVERTED INTO A FIBER NODE THAT DESCRIBES

THE WORK THAT NEEDS TO BE DONE. 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.
23. ### 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. A UNIT OF WORK. EACH ELEMENT IS CONVERTED INTO A FIBER NODE THAT DESCRIBES THE WORK THAT NEEDS TO BE DONE.
24. ### 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. A UNIT OF WORK. EACH ELEMENT IS CONVERTED INTO A FIBER NODE THAT DESCRIBES THE WORK THAT NEEDS TO BE DONE. AND THAT MAKES IT A CONVENIENT WAY TO TRACK, SCHEDULE, PAUSE AND ABORT THE WORK.
25. ### Visualizing Units of Work INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU

WANTED A TLDR FOR

27. None
28. None
29. ### 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; }
30. ### 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; } ๐ป
31. None

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

WANTED A TLDR FOR

36. ### โโฆ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. ๐ป
37. ### CODE = DATA โโฆ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. ๐ป
38. ### โ REACT ELEMENTS ARE JUST DATA โ JUST LIKE IN

LISP, REACT COMPONENTS CAN MANIPULATE THEIR CHILDREN AND RETURN COMPLETELY DIFFERENT THINGS

40. None
41. ### / / . . . 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 > > ; } / / . . .

FOR

FOR
45. None

47. ### 1. A GENERATOR (PRODUCER) THAT CAN ALSO CONSUME VALUES. โ

JAVASCRIPT GENERATORS CAN CONSUME VALUES โ BY THIS DEFINITION, THEY ARE COROUTINES

49. ### 2. โ 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 A GENERATOR THAT CAN RESOLVE ASYNCHRONOUS VALUES, LIKE ASYNC/AWAIT.

51. ### 3. โ = DEEP AWAIT โ WITH SUSPENSE, WE CAN

PAUSE RECONCILIATION AT ANY DEPTH A GENERATOR THAT CAN YIELD WITH A STACKFUL CONTINUATION ๐ป
52. ### 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
53. ### 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

A TLDR FOR
55. ### 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.

57. ### โ COROUTINES PER SI IN REACT NO LONGER EXIST. โ

IT WILL BE FASCINATING TO SEE WHAT FORM COROUTINES TAKE WHEN THEY RETURN TO REACT FIBER.
58. ### Coroutines & Concurrent React INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU

WANTED A TLDR FOR

60. ### 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>; }
61. None

63. ### 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>; }
64. ### 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>; }
65. ### 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 INSIDE AN INFINITE LOOP. / / DOING CONCURRENT STUFF.
66. None
67. ### 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; } } } ๐ป
68. ### 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; } } } ๐ป

70. ### 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>; }
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 [_, startTransition] = useTransition(); const [result, setResult] = useState(""); useEffect(() = > { startTransition(() = > { const newResult = resourcefulOperation(props.value); setResult(newResult); }); }, [props.value]); return <p>{result}</p>; }
72. None

74. ### โ THEREโS NO USE OF WORKERS OR WASM FOR PARALLELISM

โ THEREโS A COOPERATIVE MULTITASKING MODEL โ A SINGLE RENDERING THREAD, BUT INTERRUPTIBLE SO THAT RENDERING CAN BE INTERLEAVED WITH OTHER MAIN THREAD TASKS AND OTHER REACT RENDERS

76. ### โ AN UPDATE CAN HAPPEN IN THE BACKGROUND, WITHOUT BLOCKING

ANOTHER IN RESPONSE TO NEW INPUT โ THE SCHEDULER SWITCHES TO THE MORE URGENT RENDERING TASK, THEN PICKS THE ORIGINAL TASK UP AFTER THAT HAS FINISHED
77. ### โ IT YIELDS EXECUTION IS BACK TO THE MAIN THREAD

EVERY 5MS โ IT'S SMALLER THAN A SINGLE FRAME EVEN ON 120FPS DEVICES, SO IT WON'T BLOCK ANIMATIONS โ MOST INDIVIDUAL COMPONENTS DON'T TAKE LONGER THAN A SINGLE FRAME TO RENDER โ IN PRACTICE, RENDERING IS EFFECTIVELY INTERRUPTIBLE

TLDR FOR

FOR
80. ### โ 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. ๐ป

82. ### 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'; } }
83. ### 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'; } }
84. ### 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
85. ### Effect handlers in React INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU

WANTED A TLDR FOR

88. ### THE REACT TEAM APPARENTLY SPENT SOME TIME EXPERIMENTING WITH EFFECT-HANDLER

CONTROL STRUCTURES FOR MANAGING LAYOUT

94. ### 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) ); }
95. ### 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

99. ### A COMPONENT IS ABLE TO SUSPEND THE FIBER IT IS

RUNNING IN BY THROWING A PROMISE, WHICH IS CAUGHT AND HANDLED BY THE FRAMEWORK.
100. ### THROW โ HANDLE โ RESUME PATTERN. A COMPONENT IS ABLE

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

FOR
102. ### 1. REACT FIBER WAS A REWRITE OF REACT FOCUSED ON

GIVING MORE LOW-LEVEL CONTROL OVER PROGRAM EXECUTION
103. ### 1. โ 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 LOW-LEVEL CONTROL OVER PROGRAM EXECUTION
104. ### 2. REACT TRIES TO ADDRESS THE LACK OF SOME JAVASCRIPT

FEATURES/LANGUAGE-LEVEL RESOURCES BY IMPLEMENTING SOME ALTERNATIVE SOLUTIONS TO ACHIEVE SIMILAR BEHAVIORS
105. ### 3. UNDERSTANDING THESE INTERNALS AND THEIR RATIONALES HELPS US IMPLEMENT

OUR OWN ABSTRACTIONS

108. None
109. ### 5. 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
110. None
111. ### 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.

113. None

115. None
116. None
117. None