↝ 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
Slide 18
Slide 18 text
Fibers as
Units of Work
INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR FOR
Slide 19
Slide 19 text
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.
Slide 20
Slide 20 text
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.
Slide 21
Slide 21 text
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.
Slide 22
Slide 22 text
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.
Slide 23
Slide 23 text
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.
Slide 24
Slide 24 text
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.
Slide 25
Slide 25 text
Visualizing
Units of Work
INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR FOR
Slide 26
Slide 26 text
🤓💻
EXPERIMENT #1
INSPECTING ELEMENTS
Slide 27
Slide 27 text
No content
Slide 28
Slide 28 text
No content
Slide 29
Slide 29 text
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;
}
Slide 30
Slide 30 text
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;
}
🍻
Manipulating
Units of Work
INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR FOR
Slide 35
Slide 35 text
🙋✋
QUESTION #1
HAVE YOU EVER HEARD ABOUT HOMOICONICITY?
Slide 36
Slide 36 text
“…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.
🍻
Slide 37
Slide 37 text
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.
🍻
Slide 38
Slide 38 text
↝ REACT ELEMENTS ARE JUST DATA
↝ JUST LIKE IN LISP, REACT COMPONENTS CAN
MANIPULATE THEIR CHILDREN AND RETURN
COMPLETELY DIFFERENT THINGS
Coroutines
INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR FOR
Slide 44
Slide 44 text
Overview
INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR FOR
Slide 45
Slide 45 text
No content
Slide 46
Slide 46 text
1. A GENERATOR (PRODUCER) THAT
CAN ALSO CONSUME VALUES.
Slide 47
Slide 47 text
1.
A GENERATOR (PRODUCER) THAT
CAN ALSO CONSUME VALUES.
↝ JAVASCRIPT GENERATORS CAN
CONSUME VALUES
↝ BY THIS DEFINITION, THEY ARE
COROUTINES
Slide 48
Slide 48 text
2. A GENERATOR THAT CAN RESOLVE
ASYNCHRONOUS VALUES, LIKE
ASYNC/AWAIT.
Slide 49
Slide 49 text
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.
Slide 50
Slide 50 text
3. A GENERATOR THAT CAN YIELD
WITH A STACKFUL CONTINUATION
Slide 51
Slide 51 text
3. ↝ = DEEP AWAIT
↝ WITH SUSPENSE, WE CAN
PAUSE RECONCILIATION AT ANY
DEPTH
A GENERATOR THAT CAN YIELD
WITH A STACKFUL CONTINUATION
🍻
Slide 52
Slide 52 text
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
Slide 53
Slide 53 text
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
Slide 54
Slide 54 text
Coroutines &
React
INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR FOR
Slide 55
Slide 55 text
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.
Slide 56
Slide 56 text
HTTPS://GITHUB.COM/FACEBOOK/REACT/
PULL/6859
Slide 57
Slide 57 text
↝ COROUTINES PER SI IN REACT NO LONGER EXIST.
↝ IT WILL BE FASCINATING TO SEE WHAT FORM
COROUTINES TAKE WHEN THEY RETURN TO REACT FIBER.
Slide 58
Slide 58 text
Coroutines &
Concurrent
React
INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR FOR
Slide 59
Slide 59 text
HTTPS://WWW.YOUTUBE.COM/WATCH?
V=NLF0N9SACD4
Slide 60
Slide 60 text
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
{result}
;
}
Slide 61
Slide 61 text
No content
Slide 62
Slide 62 text
🤓💻
EXPERIMENT #3
BUILDING A COROUTINES-BASED SCHEDULER
Slide 63
Slide 63 text
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
{result}
;
}
Slide 64
Slide 64 text
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
{result}
;
}
Slide 65
Slide 65 text
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
{result}
;
}
/
/
PROMOTED TO A GENERATOR.
/
/
YIELDING INSIDE AN INFINITE LOOP.
/
/
DOING CONCURRENT STUFF.
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
{result}
;
}
Slide 71
Slide 71 text
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
{result}
;
}
Slide 72
Slide 72 text
No content
Slide 73
Slide 73 text
YES, WE DID 🤓
(USING SOME COROUTINES MAGIC)
Slide 74
Slide 74 text
↝ 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
Slide 75
Slide 75 text
↓ ORIGINAL RENDER TASK
USER INPUT →
↑ HIGHER PRIORITY RENDER TASK
↓ RESUME ORIGINAL RENDER TASK
Slide 76
Slide 76 text
↝ 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
Slide 77
Slide 77 text
↝ 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
Slide 78
Slide 78 text
Effect Handlers
INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR FOR
Slide 79
Slide 79 text
Overview
INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR FOR
Slide 80
Slide 80 text
↝ 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.
🍻
A COMPONENT IS ABLE TO SUSPEND THE
FIBER IT IS RUNNING IN BY THROWING A
PROMISE, WHICH IS CAUGHT AND
HANDLED BY THE FRAMEWORK.
Slide 100
Slide 100 text
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.
Slide 101
Slide 101 text
Conclusions
INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR FOR
Slide 102
Slide 102 text
1. REACT FIBER WAS A REWRITE OF
REACT FOCUSED ON GIVING MORE
LOW-LEVEL CONTROL OVER
PROGRAM EXECUTION
Slide 103
Slide 103 text
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
Slide 104
Slide 104 text
2. REACT TRIES TO ADDRESS THE
LACK OF SOME JAVASCRIPT
FEATURES/LANGUAGE-LEVEL
RESOURCES BY IMPLEMENTING
SOME ALTERNATIVE SOLUTIONS TO
ACHIEVE SIMILAR BEHAVIORS
Slide 105
Slide 105 text
3. UNDERSTANDING THESE
INTERNALS AND THEIR
RATIONALES HELPS US IMPLEMENT
OUR OWN ABSTRACTIONS
Slide 106
Slide 106 text
HTTPS://WWW.YOUTUBE.COM/WATCH?
V=ADNJ3FYDEAO
Slide 107
Slide 107 text
4. REACT IS NOT REACTIVE, BUT IT
FEELS CONCURRENT
Slide 108
Slide 108 text
No content
Slide 109
Slide 109 text
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
Slide 110
Slide 110 text
No content
Slide 111
Slide 111 text
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.
Slide 112
Slide 112 text
6. DON’T ALWAYS TRUST ALL OF MY
SPECULATIONS/FUTURE
PREDICTIONS 🤷