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;
};
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();
});