Measuring the performance of JSS apps
Tags: sitecore, jss, javascript, performance
Published: 2023-07-18 21:01:32

In the scope of this article, I would like to share with you tools and approach that the JSS team uses internally to measure the performance of sample apps.
For this purpose, we are using some libraries:
* [Clinic.js](https://clinicjs.org/) - performance analysis tooling.
* [k6](https://k6.io/) - load testing tool that provides an easy way to make performance testing.

I'm using [node-headless-ssr-proxy app](https://github.com/Sitecore/jss/tree/dev/packages/create-sitecore-jss/src/templates/node-headless-ssr-proxy) + [react app](https://github.com/Sitecore/jss/tree/dev/packages/create-sitecore-jss/src/templates/react) scaffolded by [create-sitecore-jss](https://www.npmjs.com/package/create-sitecore-jss). 
To setup all the things appropriately, follow the next steps:

#### 1. Install _k6_
Follow documentation [steps](https://k6.io/docs/get-started/installation/).
In my case it's a Windows machine, so I run

```
choco install k6
```
#### 2. Implement _k6_ script to perform load testing

**loadTesting.js**

```javascript
import http from 'k6/http';
import { sleep, group, check } from 'k6';
import { Trend, Counter } from 'k6/metrics';

// load test settings
export const options = {
  discardResponseBodies: true,
  scenarios: {
    contacts: {
      // scenario name
      executor: 'ramping-vus',
      // VUs - virtual users
      startVUs: 1,
      stages: [
        { duration: '2m', target: 100 },
        { duration: '10m', target: 100 },
      ],
      gracefulRampDown: '0s',
    },
  },
};

const pageTrend = new Trend('Page_Trend', true);
const pageCount = new Counter('Page_Count');

// execute test
export default function() {
  // point to the page of your sample app
  const rootUrl = 'http://localhost:3000/styleguide';

  // generate page hit
  group('JSS Sample Application', function() {
    const response = http.get(rootUrl);

    check(response, {
      'Response 200': (r) => r.status === 200,
    });

    if (response.status === 200) {
      // add a successful record to compare with total page hit counts
      pageTrend.add(response.timings.duration);
      pageCount.add(1);
    }

    sleep(1);
  });
}	
```
#### 3. Install _Clinic.js_
```
npm install -g clinic
```
#### 4. Compile node-headless-ssr-proxy app
```
.\node_modules\.bin\tsc 
```
#### 5. Collect metrics
In order to start clinic.js command we need an entry point to load the testing script (_loadTesting.js_) and specify the entry point of the headless app (_index.js_) we compiled previously. _Clinic_ will start headless app and after that perform load testing.
* Generate [Doctor](https://clinicjs.org/doctor/) graphs. It will help us to diagnose performance issues in the headless app.
```
clinic doctor --on-port 'k6 run ./loadTesting.js' -- node ./src/index.js
```
![Doctor](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e5ndu7uh2bbbpziphc1u.png)
* Generate [Flame](https://clinicjs.org/flame/) graph. It shows the bottlenecks and hot paths in your code.
![Flame](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v27klc7ppcqh0qxp3em4.png)
* Generate [Heap Profiler](https://clinicjs.org/heapprofiler/). Uncovers memory allocations by functions with Flamegraphs.
![Heap Profiler](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u5up11538cvemokj6liz.png)
* Analyze metrics provided in console
![Console](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l024pkyao9vehtefn8hb.png)

### Wrap up :sunglasses:
That's all for this article. Based on the information that we generated, you can deeply investigate performance issues if you encountered any. For us these tools are extremely helpful.
I hope it was useful to you to know a bit more about performance profiling. Thank you for your attention! See you in [**LinkedIn**](https://www.linkedin.com/in/illia-kovalenko-045a45150/) [**Instagram**](https://www.instagram.com/illia__kovalenko) [**GitHub**](https://github.com/illiakovalenko) :wave: