Simple implementation 🤓

1. Add alias for react-dom/profiler

To make profiling work in a production environment, we need to add an alias for react-dom/profiler and scheduler/tracing to .babelrc file.

Before we edit the file, we need to install this package babel-plugin-module-resolver , which bring us alias functionality.

yarn add -D babel-plugin-module-resolver

Once we got the babel plugin installed, we modify .babelrc like this:

2. Add Profiler component

We will import unstable_Profiler from React and make an alias to make our code more readable.

Implementing Profiler itself is very straightforward. Just wrap any part of code you want to measure.

Last step is to listen for onRender callback and console.log metrics with logMeasurement function. As you can see, the function is asynchronous–this part is for when we later implement Firebase Performance.

Here is a quick overview of what onRender function will return:

id: string - The id value of the Profiler tag that was measured.

phase: “mount" | “update"- Identifies whether this component has just been mounted or re-rendered, due to a change in state or props.

actualDuration: number - Time spent rendering the Profiler and its descendants for the most recent "mount" or "update" render.

baseDuration: number - Duration of the most recent render time for each individual component within the Profiler tree.

Add Performance Monitoring

I’m putting the final code upfront, so I can go through each part separately.

Since I’m initializing trace in componentDidMount I have to cache values from initial render in variables initialMount and initialUpdates, and later record those data (line 21, 22).

I’m also using the traceStarted variable to track if trace has started. The current implementation of Firebase Perf Tool is asynchronous. The good news is that in an upcoming release, the perf tools should become synchronous (I would keep an eye on those release notes).

To keep this example very simple, I’m recording the mount time as initialMount (if components re-mount, it will record last mount) and counter as updates, measuring the number of times component re-renders.

On top of the initialMount and update, we are also able to record how long each re-render takes. It almost seems like the possibilities are almost endless 🤩

With this simple approach, we can add performance tracking to our most important components.

To make code more reusable, we can create our own higher-order component (HOC) for the Profiler component, and include all of our additional logic.

Should I use it in production? 🙇‍

This is a tricky question at the time of writing this article, since the whole feature is still flagged as unstable, and React is not using asynchronous rendering.

We can expect some minor drawbacks when using the profiler in production. Let’s take a closer look at two issues, with which I’m mostly concerned: how much additional commit time will Profiler adds to our components, and how much our bundle size will increase.