diff --git a/README.md b/README.md index 5ea3a81..35c4fbd 100644 --- a/README.md +++ b/README.md @@ -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 @@ -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. @@ -188,4 +197,4 @@ export default ({ } ``` -Learn more about getting started here https://coryrylan.com/blog/testing-web-performance-with-web-test-runner \ No newline at end of file +Learn more about getting started here https://coryrylan.com/blog/testing-web-performance-with-web-test-runner diff --git a/package-lock.json b/package-lock.json index fe1d582..edf23c6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,11 +1,12 @@ { "name": "web-test-runner-performance", - "version": "0.0.4", + "version": "0.1.4", "lockfileVersion": 2, "requires": true, "packages": { "": { - "version": "0.0.4", + "name": "web-test-runner-performance", + "version": "0.1.4", "license": "MIT", "dependencies": { "@rollup/plugin-alias": "^3.1.5", diff --git a/src/browser.ts b/src/browser.ts index a25fb30..fa3dad3 100644 --- a/src/browser.ts +++ b/src/browser.ts @@ -7,6 +7,10 @@ export async function testBundleSize(bundle: string, config: { optimize?: boolea return await executeServerCommand('performance:bundle', { bundle, config }); } +export async function testFileSize(filepath) { + return await executeServerCommand('performance:filesize', { filepath } ) +} + export async function testRenderTime(template: TemplateResult<1>, config: { iterations?: number, average?: number } = { }) { const conf = { iterations: 1, average: 3, ...config }; let averages = []; diff --git a/src/index.performance.ts b/src/index.performance.ts index 59c2f0d..0c5f730 100644 --- a/src/index.performance.ts +++ b/src/index.performance.ts @@ -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 () => { @@ -12,6 +12,11 @@ describe('performance', () => { it('should meet maximum render time 1000

below 50ms', async () => { const result = await testRenderTime(html`

hello world

`, { 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) + }) }); diff --git a/src/index.ts b/src/index.ts index bfee975..8b54dad 100644 --- a/src/index.ts +++ b/src/index.ts @@ -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() { @@ -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', diff --git a/web-test-runner.config.mjs b/web-test-runner.config.mjs index de3239e..5025e3e 100644 --- a/web-test-runner.config.mjs +++ b/web-test-runner.config.mjs @@ -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, @@ -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 }),