diff --git a/packages/e2e-tests/config/performance-reporter.js b/packages/e2e-tests/config/performance-reporter.js index f7bb05666054d5..03bb99795f848b 100644 --- a/packages/e2e-tests/config/performance-reporter.js +++ b/packages/e2e-tests/config/performance-reporter.js @@ -4,6 +4,11 @@ function average( array ) { return array.reduce( ( a, b ) => a + b ) / array.length; } +function round( number, decimalPlaces = 2 ) { + const factor = Math.pow( 10, decimalPlaces ); + return Math.round( number * factor ) / factor; +} + class PerformanceReporter { onRunComplete() { const path = __dirname + '/../specs/performance/results.json'; @@ -17,11 +22,11 @@ class PerformanceReporter { // eslint-disable-next-line no-console console.log( ` -Average time to load: ${ average( load ) }ms -Average time to DOM content load: ${ average( domcontentloaded ) }ms -Average time to type character: ${ average( type ) }ms -Slowest time to type character: ${ Math.max( ...type ) }ms -Fastest time to type character: ${ Math.min( ...type ) }ms +Average time to load: ${ round( average( load ) ) }ms +Average time to DOM content load: ${ round( average( domcontentloaded ) ) }ms +Average time to type character: ${ round( average( type ) ) }ms +Slowest time to type character: ${ round( Math.max( ...type ) ) }ms +Fastest time to type character: ${ round( Math.min( ...type ) ) }ms ` ); } } diff --git a/packages/e2e-tests/specs/performance/performance.test.js b/packages/e2e-tests/specs/performance/performance.test.js index 0bdc172682fafc..b4ba1419bb9475 100644 --- a/packages/e2e-tests/specs/performance/performance.test.js +++ b/packages/e2e-tests/specs/performance/performance.test.js @@ -2,7 +2,7 @@ * External dependencies */ import { join } from 'path'; -import { existsSync, readFileSync, writeFileSync } from 'fs'; +import { existsSync, readFileSync, unlinkSync, writeFileSync } from 'fs'; /** * WordPress dependencies @@ -19,6 +19,48 @@ function readFile( filePath ) { : ''; } +function deleteFile( filePath ) { + if ( existsSync( filePath ) ) { + unlinkSync( filePath ); + } +} + +function isKeyEvent( item ) { + return ( + item.cat === 'devtools.timeline' && + item.name === 'EventDispatch' && + item.dur && + item.args && + item.args.data + ); +} + +function isKeyDownEvent( item ) { + return isKeyEvent( item ) && item.args.data.type === 'keydown'; +} + +function isKeyPressEvent( item ) { + return isKeyEvent( item ) && item.args.data.type === 'keypress'; +} + +function isKeyUpEvent( item ) { + return isKeyEvent( item ) && item.args.data.type === 'keyup'; +} + +function getEventDurationsForType( trace, filterFunction ) { + return trace.traceEvents + .filter( filterFunction ) + .map( ( item ) => item.dur / 1000 ); +} + +function getEventDurations( trace ) { + return [ + getEventDurationsForType( trace, isKeyDownEvent ), + getEventDurationsForType( trace, isKeyPressEvent ), + getEventDurationsForType( trace, isKeyUpEvent ), + ]; +} + describe( 'Performance', () => { it( '1000 paragraphs', async () => { const html = readFile( @@ -49,28 +91,58 @@ describe( 'Performance', () => { }; let i = 1; - let startTime; - - await page.on( 'load', () => - results.load.push( new Date() - startTime ) - ); - await page.on( 'domcontentloaded', () => - results.domcontentloaded.push( new Date() - startTime ) - ); while ( i-- ) { - startTime = new Date(); await page.reload( { waitUntil: [ 'domcontentloaded', 'load' ] } ); + const timings = JSON.parse( + await page.evaluate( () => + JSON.stringify( window.performance.timing ) + ) + ); + const { + navigationStart, + domContentLoadedEventEnd, + loadEventEnd, + } = timings; + results.load.push( loadEventEnd - navigationStart ); + results.domcontentloaded.push( + domContentLoadedEventEnd - navigationStart + ); } await insertBlock( 'Paragraph' ); i = 200; + const traceFile = __dirname + '/trace.json'; + + await page.tracing.start( { + path: traceFile, + screenshots: false, + categories: [ 'devtools.timeline' ], + } ); while ( i-- ) { - startTime = new Date(); await page.keyboard.type( 'x' ); - results.type.push( new Date() - startTime ); + } + + await page.tracing.stop(); + + const traceResults = JSON.parse( readFile( traceFile ) ); + const [ + keyDownEvents, + keyPressEvents, + keyUpEvents, + ] = getEventDurations( traceResults ); + + if ( + keyDownEvents.length === keyPressEvents.length && + keyPressEvents.length === keyUpEvents.length + ) { + for ( let j = 0; j < keyDownEvents.length; j++ ) { + results.type.push( + keyDownEvents[ j ] + keyPressEvents[ j ] + keyUpEvents[ j ] + ); + } } writeFileSync( @@ -78,6 +150,8 @@ describe( 'Performance', () => { JSON.stringify( results, null, 2 ) ); + deleteFile( traceFile ); + expect( true ).toBe( true ); } ); } );