Skip to content

Instantly share code, notes, and snippets.

@mfrachet
Last active March 6, 2023 06:20
Show Gist options
  • Save mfrachet/c50f7f4bd2031a3191e965f898d3bc34 to your computer and use it in GitHub Desktop.
Save mfrachet/c50f7f4bd2031a3191e965f898d3bc34 to your computer and use it in GitHub Desktop.
Profiling react in tests.md

Create the HoC

import React from "react";

export const profile = (Component) => {
  const handleRender = (
    id, // the "id" prop of the Profiler tree that has just committed
    phase, // either "mount" (if the tree just mounted) or "update" (if it re-rendered)
    actualDuration, // time spent rendering the committed update
    baseDuration, // estimated time to render the entire subtree without memoization
    startTime, // when React began rendering this update
    commitTime, // when React committed this update
    interactions
  ) => {
    ProfiledComponent.updates.push({
      id,
      phase,
      actualDuration,
      baseDuration,
      startTime,
      commitTime,
      interactions,
    });
  };

  const ProfiledComponent = (props) => (
    <React.Profiler
      id={`Profiled${Component.name || `UnknownComponent`}`}
      onRender={handleRender}
    >
      <Component {...props} />
    </React.Profiler>
  );

  ProfiledComponent.updates = [];
  ProfiledComponent.commitCount = () => ProfiledComponent.updates.length;
  ProfiledComponent.updateCount = () =>
    ProfiledComponent.updates.filter((c) => c.phase === "update").length;

  return ProfiledComponent;
};

In the test

import React from "react";
import { fireEvent, render } from "@testing-library/react";
import { profile } from "./ReactProfiler";
import App from "./App";

test("renders learn react link", () => {
  const ProfiledApp = profile(App);
  const { getByText } = render(<ProfiledApp />);

  const btn = getByText(/Increment/i);
  fireEvent.click(btn);
  fireEvent.click(btn);
  fireEvent.click(btn);
  fireEvent.click(btn);

  expect(ProfiledApp.commitCount()).toBe(5); // counts updates + mount phases
  expect(ProfiledApp.updateCount()).toBe(4); // counts only the update phases
  expect(getByText(/4/i)).toBeInTheDocument();
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment