Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generic Profiling story to wrap any component #5341

Merged
merged 30 commits into from
May 15, 2024

Conversation

lucasbordeau
Copy link
Contributor

@lucasbordeau lucasbordeau commented May 8, 2024

This PR introduces a Profiling feature for our story book tests.

It also implements a new CI job : front-sb-test-performance, that only runs stories suffixed with .perf.stories.tsx

How it works

It allows to wrap any component into an array of React Profiler components that will run tests many times to have the most replicable average render time possible.

It is simply used by calling the new getProfilingStory util.

Internally it creates a defined number of tests, separated by an arbitrary waiting time to allow the CPU to give more stable results.

It will do 3 warm-up and 3 finishing runs of tests because the first and last renders are always a bit erratic, so we want to measure only the runs in-between.

On the UI side it gives a table of results :

image

On the programmatic side, it stores the result in a div that can then be parsed by the play fonction of storybook, to expect a defined threshold.

play: async ({ canvasElement }) => {
    await findByTestId(
      canvasElement,
      'profiling-session-finished',
      {},
      { timeout: 60000 },
    );

    const profilingReport = getProfilingReportFromDocument(canvasElement);

    if (!isDefined(profilingReport)) {
      return;
    }

    const p95result = profilingReport?.total.p95;

    expect(
      p95result,
      `Component render time is more than p95 threshold (${p95ThresholdInMs}ms)`,
    ).toBeLessThan(p95ThresholdInMs);
  },

@lucasbordeau lucasbordeau changed the title Working generic Profiling story to wrap any component Generic Profiling story to wrap any component May 8, 2024
Copy link
Member

@charlesBochet charlesBochet left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very nice! Could you just fix the failing sb test?

@lucasbordeau lucasbordeau merged commit cfacdfc into main May 15, 2024
11 of 12 checks passed
@lucasbordeau lucasbordeau deleted the feat/add-storybook-performance-test branch May 15, 2024 11:50
arnavsaxena17 pushed a commit to arnavsaxena17/twenty that referenced this pull request Oct 6, 2024
This PR introduces a Profiling feature for our story book tests.

It also implements a new CI job : front-sb-test-performance, that only
runs stories suffixed with `.perf.stories.tsx`

## How it works 

It allows to wrap any component into an array of React Profiler
components that will run tests many times to have the most replicable
average render time possible.

It is simply used by calling the new `getProfilingStory` util.

Internally it creates a defined number of tests, separated by an
arbitrary waiting time to allow the CPU to give more stable results.

It will do 3 warm-up and 3 finishing runs of tests because the first and
last renders are always a bit erratic, so we want to measure only the
runs in-between.

On the UI side it gives a table of results : 

<img width="515" alt="image"
src="https://github.com/twentyhq/twenty/assets/26528466/273d2d91-26da-437a-890e-778cb6c1f993">

On the programmatic side, it stores the result in a div that can then be
parsed by the play fonction of storybook, to expect a defined threshold.

```tsx
play: async ({ canvasElement }) => {
    await findByTestId(
      canvasElement,
      'profiling-session-finished',
      {},
      { timeout: 60000 },
    );

    const profilingReport = getProfilingReportFromDocument(canvasElement);

    if (!isDefined(profilingReport)) {
      return;
    }

    const p95result = profilingReport?.total.p95;

    expect(
      p95result,
      `Component render time is more than p95 threshold (${p95ThresholdInMs}ms)`,
    ).toBeLessThan(p95ThresholdInMs);
  },
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants