Incorporating Tim's feedback.

master
Thomas Hintz 4 years ago
parent 68c84b57d0
commit 5e1b58833b

@ -30,16 +30,14 @@ gain an understanding of the real React and how to build
high-performance applications with it. high-performance applications with it.
This book is based on the first chapter of the book /High-Performance This book is based on the first chapter of the book /High-Performance
React/. If you enjoy /Foundations of High-Performance React React/. If you enjoy this book and you want to learn more practical
Applications/ and you want to learn more practical ways to utilize the ways to utilize the foundations we will learn here and get a more
foundations we will learn here and get a more detailed blue-print for detailed blue-print for creating high performance React applications,
creating high performance React applications, then be sure to check then be sure to check out /High-Performance React/.
out /High-Performance React/.
/Foundations of High-Performance React Applications/ is not intended This book is not intended to be an introduction to React or
to be an introduction to React or JavaScript. While it might be useful JavaScript. While it might be useful to beginners, this book assumes
to beginners, this book assumes familiarity with both JavaScript and familiarity with both JavaScript and React.
React.
And while this book only specifically addresses React-DOM the And while this book only specifically addresses React-DOM the
foundations apply equally to React-Native and other React foundations apply equally to React-Native and other React
@ -109,11 +107,17 @@ does.
:EXPORT_FILE_NAME: manuscript/components-of-react.markua :EXPORT_FILE_NAME: manuscript/components-of-react.markua
:END: :END:
Conceptually React is very simple. It starts by walking a tree of The primary elements that make up any React program are its
components and building up a tree of their output. Then it compares components. A ~component~ in React maintains local state and "renders"
that tree to the tree currently in the browser's DOM to find any output to eventually be included in the browser's DOM. A tree of
differences between them. When it finds differences it updates the components is then created whenever a component outputs other
browser's DOM to match its internal tree. components.
So, conceptually, React's core algorithm is very simple: it starts by
walking a tree of components and building up a tree of their
output. Then it compares that tree to the tree currently in the
browser's DOM to find any differences between them. When it finds
differences it updates the browser's DOM to match its internal tree.
But what does that actually look like? If your app is janky does that But what does that actually look like? If your app is janky does that
explanation point you towards what is wrong? No. It might make you explanation point you towards what is wrong? No. It might make you
@ -291,8 +295,8 @@ are not relevant to our study here.
#+BEGIN_SRC javascript #+BEGIN_SRC javascript
function createElement(node) { function createElement(node) {
// if array (not text, number, or other primitive) // if array (our representation of an element)
if (typeof node === 'object') { if (Array.isArray(node)) {
const [ tag, props, children ] = node; const [ tag, props, children ] = node;
return { return {
type: tag, type: tag,
@ -326,7 +330,7 @@ of ~elements~ (surprise).
That's it. Now we have everything we need to actually begin the That's it. Now we have everything we need to actually begin the
process of rendering our tree to the DOM! process of rendering our tree to the DOM!
* Render * Render: Putting Elements on the Screen
:PROPERTIES: :PROPERTIES:
:EXPORT_FILE_NAME: manuscript/render.markua :EXPORT_FILE_NAME: manuscript/render.markua
:END: :END:
@ -403,7 +407,7 @@ tree in the browser's DOM! But so far we can only add things to our
tree. To be able to remove and modify the tree we need one more part: tree. To be able to remove and modify the tree we need one more part:
reconciliation. reconciliation.
* Reconciliation * Reconciliation, or How React Diffs
:PROPERTIES: :PROPERTIES:
:EXPORT_FILE_NAME: manuscript/reconciliation.markua :EXPORT_FILE_NAME: manuscript/reconciliation.markua
:END: :END:
@ -495,7 +499,11 @@ is the DOM element associated with our synthetic element and ~parent~
is a reference to the parent DOM element. is a reference to the parent DOM element.
Here we begin by adding a global object that will store our last render Here we begin by adding a global object that will store our last render
tree, keyed by the ~container~. tree, keyed by the ~container~. ~container~ refers to the browser's
DOM element that will be the parent for all of the React derived DOM
elements. This parent DOM element can only be used to render one tree
of elements at a time so it works well to use as a key for
~renderTrees~.
#+BEGIN_SRC javascript #+BEGIN_SRC javascript
const renderTrees = {}; const renderTrees = {};
@ -692,7 +700,7 @@ simulates, you'll be hitting a major performance bottleneck since
React will not only be replacing DOM elements in the browser but also React will not only be replacing DOM elements in the browser but also
tearing down and rebuilding the trees of child components. tearing down and rebuilding the trees of child components.
* Fibers * Fibers: Splitting up Render
:PROPERTIES: :PROPERTIES:
:EXPORT_FILE_NAME: manuscript/fibers.markua :EXPORT_FILE_NAME: manuscript/fibers.markua
:END: :END:

@ -1,6 +1,8 @@
# Components of React # Components of React
Conceptually React is very simple. It starts by walking a tree of components and building up a tree of their output. Then it compares that tree to the tree currently in the browser's DOM to find any differences between them. When it finds differences it updates the browser's DOM to match its internal tree. The primary elements that make up any React program are its components. A `component` in React maintains local state and "renders" output to eventually be included in the browser's DOM. A tree of components is then created whenever a component outputs other components.
So, conceptually, React's core algorithm is very simple: it starts by walking a tree of components and building up a tree of their output. Then it compares that tree to the tree currently in the browser's DOM to find any differences between them. When it finds differences it updates the browser's DOM to match its internal tree.
But what does that actually look like? If your app is janky does that explanation point you towards what is wrong? No. It might make you wonder if maybe it is too expensive to re-render the tree or if maybe the diffing React does is slow but you won't really know. When I was initially testing out different bread recipes I had guesses at why it wasn't working but I didn't really figure it out until I had a deeper understanding of how making bread worked. It's time we build up our understanding of how React works so that we can start to answer our questions with solid answers. But what does that actually look like? If your app is janky does that explanation point you towards what is wrong? No. It might make you wonder if maybe it is too expensive to re-render the tree or if maybe the diffing React does is slow but you won't really know. When I was initially testing out different bread recipes I had guesses at why it wasn't working but I didn't really figure it out until I had a deeper understanding of how making bread worked. It's time we build up our understanding of how React works so that we can start to answer our questions with solid answers.

@ -1,4 +1,4 @@
# Fibers # Fibers: Splitting up Render
The actual React implementation used to look very similar to what we've built so far, but with React 16 this has changed dramatically with the introduction of Fibers. Fibers are a name that React gives to discrete units of work during the render process. And the React reconciliation algorithm was changed to be based on small units of work instead of one large, potentially long-running call to `render`. This means that React is now able to process just part of the render phase, pause to let the browser take care of other things, and resume again. This is the underlying change the enables the experimental Concurrent Mode as well as running most hooks without blocking the render. The actual React implementation used to look very similar to what we've built so far, but with React 16 this has changed dramatically with the introduction of Fibers. Fibers are a name that React gives to discrete units of work during the render process. And the React reconciliation algorithm was changed to be based on small units of work instead of one large, potentially long-running call to `render`. This means that React is now able to process just part of the render phase, pause to let the browser take care of other things, and resume again. This is the underlying change the enables the experimental Concurrent Mode as well as running most hooks without blocking the render.

@ -22,8 +22,8 @@ That is: an object with two properties: `type` and `props`. The `props` property
{format: "javascript"} {format: "javascript"}
``` ```
function createElement(node) { function createElement(node) {
// if array (not text, number, or other primitive) // if array (our representation of an element)
if (typeof node === 'object') { if (Array.isArray(node)) {
const [ tag, props, children ] = node; const [ tag, props, children ] = node;
return { return {
type: tag, type: tag,

@ -2,9 +2,9 @@
Welcome to *Foundations of High-Performance React Applications* where we build our own simplified version of React. We will use our React to gain an understanding of the real React and how to build high-performance applications with it. Welcome to *Foundations of High-Performance React Applications* where we build our own simplified version of React. We will use our React to gain an understanding of the real React and how to build high-performance applications with it.
This book is based on the first chapter of the book *High-Performance React*. If you enjoy *Foundations of High-Performance React Applications* and you want to learn more practical ways to utilize the foundations we will learn here and get a more detailed blue-print for creating high performance React applications, then be sure to check out *High-Performance React*. This book is based on the first chapter of the book *High-Performance React*. If you enjoy this book and you want to learn more practical ways to utilize the foundations we will learn here and get a more detailed blue-print for creating high performance React applications, then be sure to check out *High-Performance React*.
*Foundations of High-Performance React Applications* is not intended to be an introduction to React or JavaScript. While it might be useful to beginners, this book assumes familiarity with both JavaScript and React. This book is not intended to be an introduction to React or JavaScript. While it might be useful to beginners, this book assumes familiarity with both JavaScript and React.
And while this book only specifically addresses React-DOM the foundations apply equally to React-Native and other React implementations because they are all based on the same core React library and algorithms. And while this book only specifically addresses React-DOM the foundations apply equally to React-Native and other React implementations because they are all based on the same core React library and algorithms.

@ -1,4 +1,4 @@
# Reconciliation # Reconciliation, or How React Diffs
A tale of two trees. These are the two trees that people most often talk about when talking about React's "secret sauce": the virtual DOM and the browser's DOM tree. This idea is what originally set React apart. React's reconciliation is what allows you to program declaratively. Reconciliation is what makes it so we no longer have to manually update and modify the DOM whenever our own internal state changes. In a lot of ways, it is what makes React, React. A tale of two trees. These are the two trees that people most often talk about when talking about React's "secret sauce": the virtual DOM and the browser's DOM tree. This idea is what originally set React apart. React's reconciliation is what allows you to program declaratively. Reconciliation is what makes it so we no longer have to manually update and modify the DOM whenever our own internal state changes. In a lot of ways, it is what makes React, React.
@ -39,7 +39,7 @@ Notice that in every case, except deletion, we still call `render` on the elemen
Now, to get started with our render method we must make some modifications to our previous render method. First, we need to be able to store and retrieve the previous render tree. Then we need to add code to compare parts of the tree to decide if we can re-use DOM elements from the previous render tree. And last, we need to return a tree of elements that can be used in the next render as a comparison and to reference the DOM elements that we create. These new element objects will have the same structure as our current elements but we will add two new properties: `domElement` and `parent`. `domElement` is the DOM element associated with our synthetic element and `parent` is a reference to the parent DOM element. Now, to get started with our render method we must make some modifications to our previous render method. First, we need to be able to store and retrieve the previous render tree. Then we need to add code to compare parts of the tree to decide if we can re-use DOM elements from the previous render tree. And last, we need to return a tree of elements that can be used in the next render as a comparison and to reference the DOM elements that we create. These new element objects will have the same structure as our current elements but we will add two new properties: `domElement` and `parent`. `domElement` is the DOM element associated with our synthetic element and `parent` is a reference to the parent DOM element.
Here we begin by adding a global object that will store our last render tree, keyed by the `container`. Here we begin by adding a global object that will store our last render tree, keyed by the `container`. `container` refers to the browser's DOM element that will be the parent for all of the React derived DOM elements. This parent DOM element can only be used to render one tree of elements at a time so it works well to use as a key for `renderTrees`.
{format: "javascript"} {format: "javascript"}
``` ```

@ -1,4 +1,4 @@
# Render # Render: Putting Elements on the Screen
There are now only two major puzzles remaining in our quest for our own React. The next piece is: `render`. How do we go from our JSM tree of nodes, to actually displaying something on screen? To do that we will explore the `render` method. There are now only two major puzzles remaining in our quest for our own React. The next piece is: `render`. How do we go from our JSM tree of nodes, to actually displaying something on screen? To do that we will explore the `render` method.

Loading…
Cancel
Save