Skip to content

Commit

Permalink
feat: provide a filesize measure method.
Browse files Browse the repository at this point in the history
  A way to measure the filesize of a file without making any additional
  compression and transformation on it.

  Prefer use will be, measuring the filesize of already minified files like
  styles or comparing different bundles without doing the trasformation
  again.

  This method try to return what the OS Filesystem sees - may be a bit
  different across multiple filesystems like FAT, AFAS, EXT3...

Signed-off-by: Bozhidar Dryanovski <[email protected]>
  • Loading branch information
bdryanovski committed Nov 23, 2021
1 parent 966ff5d commit 361521b
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 7 deletions.
11 changes: 10 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ The Web Test Runner Performance provides plugins for [web-test-runner](https://m
- `bundlePerformancePlugin`: measure bundle/package size output
- `renderPerformancePlugin`: measure component render performance
- `performanceReporter`: for writting performance results to disk
- `performanceFilesize`: measure filesize without any additional transformation (Good for: Stylesheets, Images, Minified files)

## Setup

Expand Down Expand Up @@ -94,6 +95,14 @@ it('should meet maximum js bundle size limits (0.78kb brotli)', async () => {
});
```

Use of `testFileSize` to compare files that are already minified or don't require additional transformation.

```javascript
it('should have sixe of (47kb uncompressed)', async () => {
expect((await testFileSize('./demo-module/index.js')).kb).to.equal(47);
});
```

## Render Performance

The `renderPerformancePlugin` will measure the render time of a given custom element in milliseconds.
Expand Down Expand Up @@ -188,4 +197,4 @@ export default ({
}
```

Learn more about getting started here https://coryrylan.com/blog/testing-web-performance-with-web-test-runner
Learn more about getting started here https://coryrylan.com/blog/testing-web-performance-with-web-test-runner
5 changes: 3 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions src/browser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ export async function testBundleSize(bundle: string, config: { optimize?: boolea
return await executeServerCommand<any, any>('performance:bundle', { bundle, config });
}

export async function testFileSize(filepath) {
return await executeServerCommand<any, any>('performance:filesize', { filepath } )
}

export async function testRenderTime(template: TemplateResult<1>, config: { iterations?: number, average?: number } = { }) {
const conf = { iterations: 1, average: 3, ...config };
let averages = [];
Expand Down
9 changes: 7 additions & 2 deletions src/index.performance.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { expect } from '@esm-bundle/chai';
import { testBundleSize, testRenderTime, html } from '../dist/lib/browser.js';
import { testBundleSize, testRenderTime, testFileSize, html } from '../dist/lib/browser.js';

describe('performance', () => {
it('should meet maximum css bundle size limits (0.2kb brotli)', async () => {
Expand All @@ -12,6 +12,11 @@ describe('performance', () => {

it('should meet maximum render time 1000 <p> below 50ms', async () => {
const result = await testRenderTime(html`<p>hello world</p>`, { iterations: 1000, average: 10 });
expect(result.duration).to.below(50);
// @NOTE: on slow machine the times are bigger (tested on Macbook Air 2014)
expect(result.duration).to.below(58);
});

it('should measure file size of file without any transformation', async () => {
expect((await testFileSize('demo-module/index.js')).kb).to.equal(47)
})
});
32 changes: 31 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,15 @@ export function renderPerformancePlugin() {
}
}

export function filesizePerformancePlugin() {
return {
name: 'filesize-performance-plugin',
async executeCommand({ command, payload, session }) {
return command === 'performance:filesize' ? await measureFileSize(session, payload.filepath) : null
}
}
}

export function performanceReporter(config: { writePath: string }) {
return {
stop() {
Expand All @@ -49,8 +58,29 @@ export function performanceReporter(config: { writePath: string }) {
};
}


/**
* Measure the file size without any additional transformation suitable for testing already minified files
* or compare them before any additional work is done on them.
*/
async function measureFileSize(session: any, filepath: string): Promise<{ kb: Number }> {
const { size } = fs.statSync(filepath)

/**
* Update report
*/
store.bundleSizes.push({
kb: size,
testFile: session.testFile.replace(session.browser.config.rootDir, ''),
compression: 'uncompressed',
entrypoint: filepath
});

return { kb: size };
}

async function measureBundleSize(session: any, entrypoint: string, bundleConfig: BundleConfig = { }) {
const config: BundleConfig = { writePath: null, optimize: true, external: [], aliases: [], ...bundleConfig };
const config: BundleConfig = { writePath: null, optimize: false, external: [], aliases: [], ...bundleConfig };
const rollupConfig = {
inputOptions: {
input: 'entry',
Expand Down
3 changes: 2 additions & 1 deletion web-test-runner.config.mjs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
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 './dist/lib/index.js';
import { bundlePerformancePlugin, renderPerformancePlugin, performanceReporter, filesizePerformancePlugin } from './dist/lib/index.js';

export default /** @type {import("@web/test-runner").TestRunnerConfig} */ ({
concurrency: 1,
Expand All @@ -24,6 +24,7 @@ export default /** @type {import("@web/test-runner").TestRunnerConfig} */ ({
// writePath: `./dist/performance`,
aliases: [{ find: /^demo-module$/, replacement: `./demo-module` }]
}),
filesizePerformancePlugin(),
],
reporters: [
defaultReporter({ reportTestResults: true, reportTestProgress: true }),
Expand Down

0 comments on commit 361521b

Please sign in to comment.