https://github.com/salute-developers/perftool
Performance Testing Tool for React Components
https://github.com/salute-developers/perftool
benchmark github-actions performance performance-monitoring performance-testing react testing
Last synced: about 1 year ago
JSON representation
Performance Testing Tool for React Components
- Host: GitHub
- URL: https://github.com/salute-developers/perftool
- Owner: salute-developers
- License: mit
- Created: 2023-01-25T07:34:20.000Z (over 3 years ago)
- Default Branch: master
- Last Pushed: 2024-12-30T09:42:10.000Z (over 1 year ago)
- Last Synced: 2025-04-17T18:16:10.667Z (about 1 year ago)
- Topics: benchmark, github-actions, performance, performance-monitoring, performance-testing, react, testing
- Language: TypeScript
- Homepage:
- Size: 3.11 MB
- Stars: 16
- Watchers: 5
- Forks: 0
- Open Issues: 11
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
- Code of conduct: CODE_OF_CONDUCT.md
Awesome Lists containing this project
README
# Performance Monitoring System for React Components
[](https://www.npmjs.com/package/@salutejs/perftool)
[](https://snyk.io/advisor/npm-package/@salutejs/perftool)
[](/LICENSE)
Keep your components blazingly fast and ship your React app with no doubt.
**🍌 Native Env**: benchmark your components in the environment they usually run in.
**🎰 CI Ready**: get it to work in your Pull Requests, it's really built for that.
**🎯 Stable Results** even in unsteady envs like GitHub runners and other virtual machines.
## Table of Contents
- [Getting Started](#getting-started)
- [Configuration](#configuration)
- [Documentation](#documentation)
- [Supported environments](#supported-environments)
- [Contributing](#contributing)
- [License](#license)
## Getting Started
Install Perftool using preferred package manager.
```bash
# Yarn
yarn add --dev @salutejs/perftool
```
```bash
# NPM
npm i -D @salutejs/perftool
```
```bash
# PNPM
pnpm add -D @salutejs/perftool
```
Let's get started by writing a test for a component. First, create a `Component.tsx` module:
```tsx
import React from 'react';
const Component = ({ prop }) =>
{prop};
export default Component;
```
Then, create a module `Component.perf.tsx`. This is an entrypoint for Perftool to obtain the component:
```tsx
import React from 'react';
import Component from './Component';
export function Default() {
return ;
}
```
Now run Perftool in preview mode to test the build and check if the component renders correctly.
```bash
npx perftool --preview *.perf.tsx
```
Then, we can proceed to the actual run with following command:
```bash
npx perftool -o base.json *.perf.tsx
```
After Perftool finishes the run, `base.json` report file will appear in the current directory.
Now let's change our component, so it takes noticeably more amount of time to render it:
```tsx
import React from 'react';
const Component = ({ prop }) => (
{[...Array(1000)].map(() => (
{prop}
))}
);
export default Component;
```
Run Perftool one more time with changed output filename:
```bash
npx perftool -o changed.json *.perf.tsx
```
After Perftool finishes the run, `changed.json` report file will appear in the current directory.
Finally, let's do the comparison of our reports:
```bash
npx perftool-compare -o result.json changed.json base.json
```
After Perftool does the comparison, `result.json` report file will appear in the current directory and an error will be thrown owing to bad significant change in the reported metrics.
**🎉 Well done! You just successfully done your first performance test with Perftool!**
## Configuration
To make an additional configuration, create `perftool.config.mts` file in the root of your project, or provide a config file path with `-c ` option when running Perftool. Here's example config:
```typescript
import type { Config } from '@salutejs/perftool';
const config: Config = {
retries: 30,
include: ['src/**/*.perf.tsx'],
displayIntermediateCalculations: false,
failOnSignificantChanges: false,
modifyWebpackConfig(conf) {
/**
* Customize the build if needed
*/
return conf;
},
};
export default config;
```
Check out all the config settings and description [here](/packages/perftool/lib/config/common.ts).
Here's [example config](https://github.com/salute-developers/plasma/blob/master/perftool.config.mts).
## Documentation
There are no fancy-github-hosted docs right now, so this section consists of useful links and some nice perftool feature specs.
### beforeTest
You can run code before Perftool renders the component. This code will be run in the browser, so at this stage you can mock data through the global object.
```tsx
import React from 'react';
import Component from './Component';
export function Default() {
return ;
}
Default.beforeTest = () => {
window.mock = 123;
};
```
#### intercept
Using the intercept method, you can intercept requests and return prepared data. Useful if you need to mock some endpoint, image or file, or cancel some request (see [typings](/packages/perftool/lib/api/intercept.ts)).
```tsx
import React from 'react';
import { intercept } from '@salutejs/perftool';
import Component from './Component';
export function Default() {
return ;
}
Default.beforeTest = async () => {
await intercept({
method: 'POST',
source: '**/api/foo*', // glob-pattern
response: 'src/utils/perftool/fixtures/foo.json', // file path
});
await intercept({
method: 'GET',
responseType: 'json',
source: '**/api/bar*',
response: { foo: 'bar' },
});
await intercept({
// any http method
responseType: 'abort',
source: '**/api/baz*',
});
};
```
#### setViewport
Using the setViewport method, you can specify the size of the viewport for rendering the current component. See [typings](/packages/perftool/lib/api/viewport.ts)
```tsx
import React from 'react';
import { setViewport } from '@salutejs/perftool';
import Component from './Component';
export function Default() {
return ;
}
Default.beforeTest = async () => {
await setViewport('desktop'); // 'desktop' and 'touch' are built-in presets
};
```
### Results interpretation
Most often the following situation will occur: everything is fine, no degradation.
In this case, there is no need to do anything - we will assume that nothing bad happened.
Now let's look at the case when perftool-compare threw an error.
The result of the performance test is a comparison of the results of runs in the base and feature branches.
Here is an example of such a report, most of the fields have been omitted for readability:
```json
{
"hasSignificantNegativeChanges": true,
"result": {
"Component.perf.tsx#Default": {
"render": {
"mean": {
"old": [10, 2],
"new": [20, 4],
"change": {
"difference": 10,
"percentage": 100,
"significanceRank": "high"
}
}
}
}
}
}
```
The top-level part of the report is a field with the boolean data type **hasSignificantNegativeChanges**, which means whether there are components in the report with statistically significant negative changes. Its value is determined based on the comparison results for each component and metric. In the config you can specify which specific metrics will be aggregated in **hasSignificantNegativeChanges**.
In this case, we detect **hasSignificantNegativeChanges: true**, and now we need to find the reason. We are looking for a metric with `change.significanceRank === 'high'` and `difference > 0`. This can be one or more components/metrics. Once we have found all the candidates for degradation, we move on to the next step.
Now you need to check whether the component that failed the test has actually changed. If the component was not directly or indirectly affected in this branch, then the result is false-positive and can be ignored - sometimes on machines where jobs are run, a load change occurs, which can lead to incorrect results.
At this stage, you can begin searching for degradation in the changed component. If you are not sure if degradation actually happened, you can run a check one more time.
### Example of CI job
See [here](https://github.com/salute-developers/plasma/blob/master/.github/workflows/performance-test-pr.yml).
## Supported environments
We follow Node maintenance cycle.
| Node | 14 | 16 | 18 | 20 |
| :--: | :-: | :-: | :-: | :-: |
| | ❌ | ✅ | ✅ | ✅ |
| React | <= 16.8 | ^16.8 | ^17 | ^18 |
| :---: | :-----: | :---: | :-: | :-: |
| | ❌ | ✅ | ✅ | ✅ |
Windows support is not currently planned.
| OS | Windows | MacOS | Linux |
| :-: | :-----: | :---: | :---: |
| | ❌ | ✅ | ✅ |
## Contributing
Check out [Contribution guide](/CONTRIBUTING.md). All types of contributions are encouraged and valued.
## License
Perftool is [MIT licensed](/LICENSE).