Fix SharePoint Framework projects to enable the React DevTools profiler

By default, the build toolchain for SharePoint Framework projects that use React aren't supported by the React DevTools profiler tool. In this post, you'll learn why and how to fix it.

A few years ago, React introduced the React Profiler to React v16.5 in the React DevTools plugin available for Chromium browsers (Chrome & CrEdge) and Firefox.

Developers can use the Profiler API to collect timing information about each component that’s rendered in order to identify performance bottlenecks in React applications.

You can learn more about the React DevTools profiler from the following deep dive video from the React team: YouTube: Deep dive with the React DevTools profiler

For those of us creating React apps in SharePoint Framework (SPFx) solutions, this is a great resource for building well performing apps for your customers!

Cool right?

SPFx? Not so fast my friend…

Sure… it’s cool… but when you try to use it, you get hit with the following error:

React DevTools profiler error

React DevTools profiler error

Profiling not supported. Profiling support requires either a development or production-profiling build of React v16.5+.

What’s going on?

The error message indicates that we need React v16.5 or higher. SPFx projects haven’t used an older version of React since SPFx v1.7.1.

Warning: Profiling React projects only works in SharePoint Online
Unfortunately, this does mean that the profiler is only available on SPFx projects built for SharePoint Online because the latest version of SPFx supported in SharePoint Server on-premises is SPFx v1.4.1.

So, if we’re using a relatively modern version of SPFx (anything v1.8+) it should work, but it isn’t… why?

The issue with SPFx projects

As the error indicates, for the profiler to work, it needs either a development or production-profiling build.

The reason you’re getting this is because the profiler needs React to be present in the bundle of your project. By default, all SPFx projects exclude React from your generated bundles & instead, assume they’re already on the page as external references.

Furthermore, the profiler it needs a special profiling build, or a development build.

Understanding how SPFx bundles are generated

Before I share the solution, let’s recap how SPFx works.

The SPFx uses webpack to generate the bundles used to load our SPFx components. The build toolchain dynamically creates the webpack config when you run gulp bundle. The generated webpack configuration instructs webpack to always exclude the npm packages react & react-dom from your generated bundle.

Why? The SPFx assumes that React is already on the page, a safe assumption because SharePoint Online uses React in their components. Regardless, every SPFx project that uses React will automatically exclude these two npm packages so we don’t have to go through the process of excluding it ourselves in every project’s ./config/config.json file using the externals element.

Important: Want to learn more about customizing & extending webpack & gulp?

I cover both of these topics in two chapters of my Mastering the SharePoint Framework Ultimate course bundle.

You’ll learn how to generate sourcemaps, include them in your deployed packages, compile Markdown files to HTML, and many more tricks!

This means we have two things we need to do to enable the React DevTools profiler:

  1. Add React to the generated bundle
  2. Ensure the React version included in the bundle is a profiler friendly version

Ideally, we only want this to happen in development, never in production, because it has a significant impact on our bundles. For example, the bundle in my test projects without these changes is ~62 KB (19KB if minified in a production build). However, once I make the following changes the bundle will balloon to 1.1MB. Clearly this is only something you want to do in development, not production.

Thankfully we can solve these two issues easily just with just a few extra lines of code in our project’s ./gulpfile.js.

Fix #1: Include React in the generated bundle

Let’s first put the two npm packages back in the bundle. To do this, we need to tell webpack to not exclude them from the bundle generation.

In your project’s ./gulpfile.js, add the following code to the end of the file:

build.configureWebpack.mergeConfig({
  additionalConfiguration: (wpcfg) => {

    // if dev build, mod config for profiling react
    if (wpcfg.mode === 'development') {
      // remove externalization of react & react-dom
      wpcfg.externals = wpcfg.externals.filter((external) => {
        return ((external !== 'react') && (external !== 'react-dom'));
      });
    }

    return wpcfg;
  }
});

This code takes the configuration generated by the SPFx build toolchain and checks if we’re currently in a development build. This is true when we run gulp serve or gulp bundle without any arguments.

Then, we look at the collection of externals defined in the config and removes references to react and react-dom. Now, when webpack runs & comes across a reference to either of these two packages, it will include them in the generated bundle

Fix #2: Swap out React with a React profiler bundle

The second fix is to configure webpack to use the profiler friendly package of React when it imports it into the bundle. This is done using the webpack resolve configuration. This option lets us configure how modules are resolved.

To implement this, add the following code to your project’s ./gulpfile.js within the if statement you just added above:

// add alias for the react-dom profiler
wpcfg.resolve.alias = {
  'react-dom$': 'react-dom/profiling'
};

This tells webpack to include the module react-dom/profiling in the bundle when it comes across import statement with an exact match for react-dom.

Review & test the solution

To recap, in order to use the React DevTools profiler in SPFx projects, add the following code to add support for profiling React projects to the end of your ./gulpfile.js:

build.configureWebpack.mergeConfig({
  additionalConfiguration: (wpcfg) => {

    // if dev build, mod config for profiling react
    if (wpcfg.mode === 'development') {
      // add alias for the react-dom profiler
      wpcfg.resolve.alias = {
        'react-dom$': 'react-dom/profiling'
      };

      // remove externalization of react & react-dom
      wpcfg.externals = wpcfg.externals.filter((external) => {
        return ((external !== 'react') && (external !== 'react-dom'));
      });
    }

    return wpcfg;
  }
});

Now, run gulp serve and load your SPFx React component in the SharePoint workbench. You can now run the profiler in the dev tools:

React DevTools profiler works with SPFx projects!

React DevTools profiler works with SPFx projects!

Andrew Connell
Microsoft MVP, Full-Stack Developer & Chief Course Artisan - Voitanos LLC.
Written by Andrew Connell

Andrew Connell is a full stack developer with a focus on Microsoft Azure & Microsoft 365. He’s received Microsoft’s MVP award every year since 2005 and has helped thousands of developers through the various courses he’s authored & taught. Andrew’s the founder of Voitanos and is dedicated to helping you be the best Microsoft 365 full stack developer. He lives with his wife & two kids in Florida.

Share & Comment