Skip to content

Instantly share code, notes, and snippets.


Brian Vaughn bvaughn

View GitHub Profile
View setFocusIfFocusable.js
function setFocusIfFocusable(node) {
if (node.nodeType !== Node.ELEMENT_NODE) {
// Text and comment nodes aren't focusable.
return false;
if (node.disabled === true) {
// Disabled elements can't be focused.
return false;
bvaughn /
Last active Aug 7, 2020
`useSubscription` and `useMutableSource` tearing and deopt behavior.

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.


useSubscription (legacy mode)



How to try the new React Profiler

Before the holiday break, I was experimenting with a new profiler UI that may eventually make its way into a released version of the React DevTools. In the meanwhile, for anyone who is curious, here's how you can try this new profiler for yourself!

Building React

To start, you'll need an updated version of React that logs the new performance marks used by this profiler.

To do this, you'll need to check out PR 17772 and build it from source: yarn install && yarn build --type=NODE. (In the future I may publish an experimental release to NPM to simplify this step.)

Running the Profiler

bvaughn / trimming–
Last active Apr 9, 2020
Handy tip for trimming demo videos
View trimming–

Handy tip for trimming demo videos

Thought I'd document the process I used for trimming down my React conf demo videos in case it might be useful to someone else in the future.

Let's say I have a 40 second video named original-video.mp4, and I want to only keep the following sections (in seconds): 1-8, 10-11, 20-33

I could create 3 chunks using ffmpeg like so:

ffmpeg -i original-video.mp4 -ss 1 -t 7 piece-a.mp4 -ss 10 -t 1 piece-b.mp4 -ss 20 -t 33 piece-c.mp4

Pre-rendering virtual rows

Example list with ten total rows and a viewport large enough to display two rows.


█ - Visible row ▓ - Hidden/display-locked row ░ - Empty space (nothing rendered here)

View profiling-data.v2.json
"version": 2,
"profilingSummary": {
"commitDurations": [
bvaughn /
Last active May 7, 2020
Profiling a custom Chrome extension

Chrome's profiler ("Performance tab) is very useful for measuring JavaScript performance, but what if you want to measure the performance of a custom extension?

For example, what if I would like to profile the following interaction:

The interaction we want to profile

bvaughn / profile-data.json
Created Apr 1, 2019
Sample React DevTools profiling data export
View profile-data.json
"version": 1,
"profilingSummary": {
"commitDurations": [
bvaughn / example.jsx
Last active Sep 15, 2020
Advanced example for manually managing subscriptions in an async-safe way using hooks
View example.jsx
import React, { useMemo } from "react";
import useSubscription from "./useSubscription";
// In this example, "source" is an event dispatcher (e.g. an HTMLInputElement)
// but it could be anything that emits an event and has a readable current value.
function Example({ source }) {
// In order to avoid removing and re-adding subscriptions each time this hook is called,
// the parameters passed to this hook should be memoized.
const subscription = useMemo(
() => ({
bvaughn /
Last active Oct 7, 2020
Infinite lists and reflow

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

You can’t perform that action at this time.