Skip to content

Instantly share code, notes, and snippets.

@bvaughn
bvaughn / devtools-bridge-protocol.md
Last active Aug 5, 2021
React DevTools: Unsupported backend version
View devtools-bridge-protocol.md

Unsupported DevTools backend version

This page contains instructions for updating a local React DevTools application to match a version embedded in a renderer such as React Native. Instructions below cover NPM, Flipper, and React Native Debugger. If you use React DevTools in a different way, please let us know.

If you are viewing this page, you have likely seen one of the dialogs below:

Dialog displaying downgrade instructions for the React DevTools frontend to connect to an older backend version

<img width="400" height="233" alt="Dialog displaying upgrade instructions for the React DevTools fron

@bvaughn
bvaughn / index.md
Last active Aug 4, 2021
How to use profiling in production mode for react-dom
View index.md

React recently introduced an experimental profiler API. This page gives instructions on how to use this API in a production release of your app.

Table of Contents

Profiling in production

React DOM automatically supports profiling in development mode for v16.5+, but since profiling adds some small additional overhead it is opt-in for production mode. This gist explains how to opt-in.

@bvaughn
bvaughn / updating-subscriptions-when-props-change-example.js
Last active Jul 30, 2021
Advanced example for manually updating subscriptions in response to props changes in an async-safe way
View updating-subscriptions-when-props-change-example.js
// This is an advanced example! It is not typically required for application code.
// If you are using a library like Redux or MobX, use the container component provided by that library.
// If you are authoring such a library, use the technique shown below.
// This example shows how to safely update subscriptions in response to props changes.
// In this case, it is important to wait until `componentDidUpdate` before removing a subscription.
// In the event that a render is cancelled before being committed, this will prevent us from unsubscribing prematurely.
// We also need to be careful about how we handle events that are dispatched in between
// `getDerivedStateFromProps` and `componentDidUpdate` so that we don't put stale values into the `state`.
@bvaughn
bvaughn / index.md
Last active Jul 29, 2021
Interaction tracing with React
View index.md

Interaction tracing with React

React recently introduced an experimental profiler API. After discussing this API with several teams at Facebook, one common piece of feedback was that the performance information would be more useful if it could be associated with the events that caused the application to render (e.g. button click, XHR response). Tracing these events (or "interactions") would enable more powerful tooling to be built around the timing information, capable of answering questions like "What caused this really slow commit?" or "How long does it typically take for this interaction to update the DOM?".

With version 16.4.3, React added experimental support for this tracing by way of a new NPM package, scheduler. However the public API for this package is not yet finalized and will likely change with upcoming minor releases, so it should be used with caution.

This Gist provides some high-level docum

@bvaughn
bvaughn / useSubscription-and-useMutableSource.md
Last active Jul 28, 2021
`useSubscription` and `useMutableSource` tearing and deopt behavior.
View useSubscription-and-useMutableSource.md

useSubscription and useMutableSource1 tearing and deopt behavior.

Mounting a new tree

The tree below represents a React application mounting. During mount, two components read from an external, mutable source. The first one (List) reads version 1 of that data and the second one (Item) reads version 2.

Deopt

useSubscription (legacy mode)

N/A.

@bvaughn
bvaughn / contributing-to-react-devtools.md
Created Jul 8, 2021
Contributing to React DevTools
View contributing-to-react-devtools.md

Intrested in contributing to React DevTools, but not sure where to start? This gist should hopefully get you going.

Install project dependencies

To get started, check out the React repo:

git clone git@github.com:facebook/react.git

Next install dependencies:

cd <react-repo>
@bvaughn
bvaughn / React.unstable_Profiler.md
Last active Jun 24, 2021
Notes about the in-development React <Profiler> component
View React.unstable_Profiler.md

Profiler

React 16.4 will introduce a new Profiler component (initially exported as React.unstable_Profiler) for collecting render timing information in order to measure the "cost" of rendering for both sync and async modes.

Profiler timing metrics are significantly faster than those built around the User Timing API, and as such we plan to provide a production+profiling bundle in the future. (The initial release will only log timing information in DEV mode, although the component will still render its children- without timings- in production mode.)

How is it used?

Profiler can be declared anywhere within a React tree to measure the cost of rendering that portion of the tree. For example, a Navigation component and its descendants:

@bvaughn
bvaughn / react-lifecycle-cheatsheet.md
Last active Jun 19, 2021
React lifecycle cheatsheet
View react-lifecycle-cheatsheet.md

React lifecycle cheatsheet

Method Side effects1 State updates2 Example uses
Mounting
componentWillMount Constructor equivalent for createClass
render Create and return element(s)
componentDidMount DOM manipulations, network requests, etc.
Updating
componentWillReceiveProps Update state based on changed props
View devtools-merging-client-and-server-trees.md

Adding Server Component support to DevTools is going to be a big lift, but generally speaking there are a few initial things to work out:

  • Updating the Flight server renderer to stream server component names/types to the client.
  • Adding a new hook to DevTools for the Flight client to call.
  • Merging the server component subtrees into the DevTools client tree.

Yesterday and today I've been thinking about this last item, and I'm feeling pretty stumped at the moment. Merging the trees isn't that difficult, but preserving the tree across client updates gets nasty when it comes to things like conditionally rendered elements.

Setting performance concerns aside, even if I were to undo the merged trees, apply the client updates, and then redo the merge– I'm still not sure we would definitely end up with the correct final state.

For example, consider the following client component that accepts "children" rendered by a server component:

@bvaughn
bvaughn / infinite-lists-and-reflow.md
Last active May 24, 2021
Infinite lists and reflow
View infinite-lists-and-reflow.md

Infinite lists and reflow

In my experience, infinite lists use two basic layout strategies. The first uses absolute positioning to control where visible items are rendered. The second uses relative positioning (with top/left padding to offset for unrendered items).

In both cases, the list abstraction caches some metadata about the size of items once they have been rendered– so that it knows where to position the items that come after them.

Both of these strategies need to handle reflow. For example, changing the width of a list often affects the height of its itesm. Generally speaking, only the "window" of rendered (visible) items are remeasured in this case (because it would be too slow to rerender and remeasure all of the items before). But once a user scrolls backwards (up/left)– the list needs to account for the reflowed sizes. If it didn't, items would appear to jump up or down (depending on the delta between the previous, cached sizes and the new/reflowed sizes).

How the list deals with new sizes