npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

web-test-runner-performance

v0.1.6

Published

[![npm version](https://badge.fury.io/js/web-test-runner-performance.svg)](https://badge.fury.io/js/web-test-runner-performance) ![CI Build](https://github.com/coryrylan/web-test-runner-performance/actions/workflows/build.yml/badge.svg)

Downloads

1,235

Readme

Web Test Runner Performance

npm version CI Build

The Web Test Runner Performance provides plugins for web-test-runner to measure UI performance as well as a custom reporter for logging results. The package provides three plugins for your web-test-runner configuration.

  • bundlePerformancePlugin: measure bundle/package size output
  • renderPerformancePlugin: measure component render performance
  • performanceReporter: for writting performance results to disk

Setup

Below you can find a minimal setup. To use web-test-runner-performance create a standalone test runner separate from your standard test runner config. Performance tests should be run independent of other tests and only run one test and browser at a time for the most accurate results.

// web-test-runner.performance.mjs
import { defaultReporter } from '@web/test-runner';
import { esbuildPlugin } from '@web/dev-server-esbuild';
import { playwrightLauncher } from '@web/test-runner-playwright';

export default ({
  concurrency: 1,
  concurrentBrowsers: 1,
  nodeResolve: true,
  testsFinishTimeout: 20000,
  files: ['./src/*.performance.ts'],
  browsers: [playwrightLauncher({ product: 'chromium', launchOptions: { headless: false } })],
  reporters: [
    defaultReporter({ reportTestResults: true, reportTestProgress: true })
  ],
  plugins: [
    esbuildPlugin({ ts: true, json: true, target: 'auto', sourceMap: true }),
  ],
});

Bundle Performance

The testBundleSize takes a JavaScript module and will bunle any imports including CSS providing a final output size in Kb. The bundle is generated by Rollup and will treeshake and minify the code. This is helpful for testing library code ensuring it properly treeeshakes. You can also pass an alias config to test local file paths.

// web-test-runner.performance.mjs
...
import { bundlePerformancePlugin } from 'web-test-runner-performance';

export default ({
  ...
  plugins: [
    bundlePerformancePlugin(),
  ]
});
// component.performance.js
import { expect } from '@esm-bundle/chai';
import { testBundleSize } from 'web-test-runner-performance/browser.js';

describe('performance', () => {
  it('should meet maximum css bundle size limits (0.2kb brotli)', async () => {
    expect((await testBundleSize('./demo-module/index.css')).kb).to.below(0.2);
  });

  it('should meet maximum js bundle size limits (0.78kb brotli)', async () => {
    expect((await testBundleSize('./demo-module/index.js')).kb).to.below(0.8);
  });
});

You can also pass in an alias configuration to alias imports for local packages.

bundlePerformancePlugin({
  aliases:  [{ find: /^demo-module$/, replacement: `${process.cwd()}/demo-module` }]
})

By default bundle test will minify CSS and JavaScript. If your build/assets are already minified you can disable this option to improve test speed.

bundlePerformancePlugin({
  optimize: false
}),

Both optimize and external can be customized at a test level to override the global settings.

it('should meet maximum js bundle size limits (0.78kb brotli)', async () => {
  expect((await testBundleSize('./demo-module/index.js', { optimize: false, external: [] })).kb).to.below(0.8);
});

Render Performance

The renderPerformancePlugin will measure the render time of a given custom element in milliseconds.

// web-test-runner.performance.mjs
...
import { renderPerformancePlugin } from 'web-test-runner-performance';

export default ({
  ...
  plugins: [
    esbuildPlugin({ ts: true, json: true, target: 'auto', sourceMap: true }),
    renderPerformancePlugin(),
  ],
});

Once the plugin is added a test can be written to check how quick an element can be rendered.

// component.performance.js
import { expect } from '@esm-bundle/chai';
import { testBundleSize, testRenderTime, html } from 'web-test-runner-performance/browser.js';

describe('performance', () => {
  it(`should meet maximum render time 1000 <p> below 50ms`, async () => {
    const result = await testRenderTime(html`<my-element>hello world</my-element>`, { iterations: 1000, average: 10 });
    expect(result.average.length).to.eql(10);
    expect(result.duration).to.below(50);
  });
});

The testRenderTime takes a template of the component to render and will return how long the element took to render its first paint in miliseconds. The config accepts an iterations property to render the template n+ iterations. By default the test runner will render three times and average the results. This can be customized using the average property.

Reporter

The performanceReporter provides a custom reporter which will write all test results to a json file.

// web-test-runner.performance.mjs
import { playwrightLauncher } from '@web/test-runner-playwright';
import { esbuildPlugin } from '@web/dev-server-esbuild';
import { defaultReporter } from '@web/test-runner';
import { bundlePerformancePlugin, renderPerformancePlugin, performanceReporter } from 'web-test-runner-performance';

export default ({
  concurrency: 1,
  concurrentBrowsers: 1,
  nodeResolve: true,
  testsFinishTimeout: 20000,
  files: ['./src/*.performance.ts'],
  browsers: [playwrightLauncher({ product: 'chromium', launchOptions: { headless: false } })],
    reporters: [
    defaultReporter({ reportTestResults: true, reportTestProgress: true }),
    performanceReporter({ writePath: `${process.cwd()}/dist/performance` })
  ],
  plugins: [
    esbuildPlugin({ ts: true, json: true, target: 'auto', sourceMap: true }),
    renderPerformancePlugin(),
    bundlePerformancePlugin(),
  ]
});
// dist/performance/report.json
{
  "renderTimes": [
    {
      "testFile": "/src/index.performance.ts",
      "duration": 27.559999999999995
    }
  ],
  "bundleSizes": [
    {
      "testFile": "/src/index.performance.ts",
      "compression": "brotli",
      "kb": 0.193
    },
    {
      "testFile": "/src/index.performance.ts",
      "compression": "brotli",
      "kb": 0.78
    }
  ]
}

Learn more about getting started here https://coryrylan.com/blog/testing-web-performance-with-web-test-runner