DEV Community

Petros Plakogiannis for Cypress

Posted on

Why I Built Cypress Performance UI: A Simple Way to Measure Web Performance with Cypress

I've been working with performance testing for many years, and one thing I've learned is that performance doesn't always have to be complicated.

Sometimes, you just want to know how fast a page loads, how the browser behaves, and whether something has become slower after a change.

That's what made me start working on cypress-performance-ui, an open-source Cypress plugin.

How It Started

Over the years, I've used different tools and approaches for performance testing.

Most of the time, the focus is on APIs, backend response times, or how a system behaves under load.

But I also wanted something simple for the client side.

  • I wanted to answer questions like:
  • How long does a page take to load?
  • How quickly does the browser start receiving the response?
  • When is the page content displayed?
  • Is the page getting slower over time?

And most importantly, I wanted to check these things directly from my existing Cypress tests.

I didn't want to set up a separate performance testing tool every time I needed a quick check.

So I decided to build something myself.

Meet Cypress Performance UI

cypress-performance-ui is a small, open-source plugin that lets you collect browser performance metrics directly inside Cypress.

It uses the browser's native Performance API, so you don't need Lighthouse or another performance testing tool.

You can measure things like:

  • Total page load time
  • Time to First Byte (TTFB)
  • First Contentful Paint (FCP)
  • DOM Content Loaded
  • Load Event timing

You can also save these measurements and view them in an HTML dashboard.

Getting Started

Install the plugin:

npm install --save-dev cypress-performance-ui

Register the plugin in your cypress.config.js:

const { defineConfig } = require("cypress");
const { registerPerformancePlugin } = require("cypress-performance-ui/plugin");

module.exports = defineConfig({
  e2e: {
    setupNodeEvents(on, config) {
      registerPerformancePlugin(on, config);
      return config;
    },
  },
});
Enter fullscreen mode Exit fullscreen mode

Then import the commands in cypress/support/e2e.js (or e2e.ts):

import "cypress-performance-ui";

Now you can collect performance data from your tests.

cy.visit("https://www.google.com");

cy.generatePerformanceReport(
  "cypress/performance/reports/performance-report.html",
  "Home page"
);
Enter fullscreen mode Exit fullscreen mode

That's it!

The plugin collects the page performance metrics, saves them in a JSON file, and generates an HTML report.

Tracking Performance Over Time

One of the things I wanted was to keep historical performance results.

Measuring a page once is useful, but comparing it with previous runs is even more useful.

For example, maybe your home page normally loads in around 400 ms.

After a new release, it starts taking 700 ms.

That's something you want to notice.

With Cypress Performance UI, the measurements are saved in JSON, so you can track page load times across different test runs.

The HTML dashboard also shows charts to help you understand how performance changes over time.

Historical Performance Baselines

In the latest version, I added a feature called Historical Performance Baselines.

The idea is simple: compare the current page load time with previous measurements.

For example:

cy.visit("https://www.google.com");

cy.assertPageLoadBaseline("Home page", {
  percentile: 75,
  historyDays: 30,
  minSamples: 10,
  tolerance: 10,
});
Enter fullscreen mode Exit fullscreen mode

This tells Cypress to:

Look at the last 30 days of saved measurements for the Home page.

Calculate the 75th percentile of the page load times.

Allow an extra 10% as tolerance.

Fail the test if the current page load time is above that limit.

You need to collect enough historical measurements first. The baseline is calculated from saved results; it isn't created automatically by the assertion.

I like this approach because I don't have to manually set a fixed limit for every page.

The baseline can change as new measurements are added to the history.

PASS and FAIL Results in the Dashboard

I also wanted to make the results easier to understand.

So I added a table to the HTML dashboard showing the page name, historical baseline, actual page load time, date, and whether the test passed or failed.

There's also a pie chart showing the PASS vs FAIL ratio.

This makes it easier to see how the application is performing across different test runs.

TypeScript Support

The plugin also supports TypeScript.

You can use the same Cypress commands in JavaScript or TypeScript projects, with autocomplete and type checking.

For example:

cy.assertPageLoadBaseline("Home page", {
  percentile: 75,
  tolerance: 10,
});

Enter fullscreen mode Exit fullscreen mode

No need to rewrite the plugin or use a different API.

What's Next?

I still have ideas for improving the plugin.

I'd like to keep improving the HTML dashboard, make the performance results easier to read, and explore more ways to use it in CI pipelines.

The goal is not to replace tools like Lighthouse, JMeter, or other performance testing solutions.

I just wanted something lightweight and easy to use when I need a quick look at client-side performance during my Cypress tests.

And that's still the main idea behind this project.

Try It Out

Cypress Performance UI is open source, and I'd be happy to hear feedback, ideas, or suggestions from other QA engineers and developers.

You can find it here:

GitHub: https://github.com/pete2121/cypress-performance-ui

npm: https://www.npmjs.com/package/cypress-performance-ui

It's also listed in the official Cypress Plugin Directory as a community plugin.

Thanks for reading!

cypress #performance #testing #opensource

Top comments (0)