Skip to content

Commit

Permalink
Add search performance measure and make other measures more stable (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
youknowriad authored Aug 4, 2021
1 parent 97f8afc commit 5d5bc72
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 38 deletions.
52 changes: 34 additions & 18 deletions bin/plugin/commands/performance.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,29 +29,33 @@ const config = require( '../config' );
/**
* @typedef WPRawPerformanceResults
*
* @property {number[]} load Load Time.
* @property {number[]} type Average type time.
* @property {number[]} focus Average block selection time.
* @property {number[]} inserterOpen Average time to open global inserter.
* @property {number[]} inserterHover Average time to move mouse between two block item in the inserter.
* @property {number[]} load Load Time.
* @property {number[]} type Average type time.
* @property {number[]} focus Average block selection time.
* @property {number[]} inserterOpen Average time to open global inserter.
* @property {number[]} inserterSearch Average time to search the inserter.
* @property {number[]} inserterHover Average time to move mouse between two block item in the inserter.
*/

/**
* @typedef WPPerformanceResults
*
* @property {number=} load Load Time.
* @property {number=} type Average type time.
* @property {number=} minType Minium type time.
* @property {number=} maxType Maximum type time.
* @property {number=} focus Average block selection time.
* @property {number=} minFocus Min block selection time.
* @property {number=} maxFocus Max block selection time.
* @property {number=} inserterOpen Average time to open global inserter.
* @property {number=} minInserterOpen Min time to open global inserter.
* @property {number=} maxInserterOpen Max time to open global inserter.
* @property {number=} inserterHover Average time to move mouse between two block item in the inserter.
* @property {number=} minInserterHover Min time to move mouse between two block item in the inserter.
* @property {number=} maxInserterHover Max time to move mouse between two block item in the inserter.
* @property {number=} load Load Time.
* @property {number=} type Average type time.
* @property {number=} minType Minium type time.
* @property {number=} maxType Maximum type time.
* @property {number=} focus Average block selection time.
* @property {number=} minFocus Min block selection time.
* @property {number=} maxFocus Max block selection time.
* @property {number=} inserterOpen Average time to open global inserter.
* @property {number=} minInserterOpen Min time to open global inserter.
* @property {number=} maxInserterOpen Max time to open global inserter.
* @property {number=} inserterSearch Average time to open global inserter.
* @property {number=} minInserterSearch Min time to open global inserter.
* @property {number=} maxInserterSearch Max time to open global inserter.
* @property {number=} inserterHover Average time to move mouse between two block item in the inserter.
* @property {number=} minInserterHover Min time to move mouse between two block item in the inserter.
* @property {number=} maxInserterHover Max time to move mouse between two block item in the inserter.
*/

/**
Expand Down Expand Up @@ -111,6 +115,9 @@ function curateResults( results ) {
inserterOpen: average( results.inserterOpen ),
minInserterOpen: Math.min( ...results.inserterOpen ),
maxInserterOpen: Math.max( ...results.inserterOpen ),
inserterSearch: average( results.inserterSearch ),
minInserterSearch: Math.min( ...results.inserterSearch ),
maxInserterSearch: Math.max( ...results.inserterSearch ),
inserterHover: average( results.inserterHover ),
minInserterHover: Math.min( ...results.inserterHover ),
maxInserterHover: Math.max( ...results.inserterHover ),
Expand Down Expand Up @@ -323,6 +330,15 @@ async function runPerformanceTests( branches, options ) {
maxInserterOpen: rawResults.map(
( r ) => r[ branch ].maxInserterOpen
),
inserterSearch: rawResults.map(
( r ) => r[ branch ].inserterSearch
),
minInserterSearch: rawResults.map(
( r ) => r[ branch ].minInserterSearch
),
maxInserterSearch: rawResults.map(
( r ) => r[ branch ].maxInserterSearch
),
inserterHover: rawResults.map(
( r ) => r[ branch ].inserterHover
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export async function getAllBlockInserterItemTitles() {
// Ideally, we shouldn't use a timeout and instead check the browser is idle for
// a specific duration, but didn't manage to find a simple way to do that.
// eslint-disable-next-line no-restricted-syntax
await page.waitFor( 500 );
await page.waitForTimeout( 500 );

const inserterItemTitles = await page.evaluate( () => {
return Array.from(
Expand Down
26 changes: 23 additions & 3 deletions packages/e2e-tests/config/performance-reporter.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,14 @@ class PerformanceReporter {
}

const results = readFileSync( filepath, 'utf8' );
const { load, type, focus, inserterOpen, inserterHover } = JSON.parse(
results
);
const {
load,
type,
focus,
inserterOpen,
inserterHover,
inserterSearch,
} = JSON.parse( results );

if ( load && load.length ) {
// eslint-disable-next-line no-console
Expand Down Expand Up @@ -80,6 +85,21 @@ Fastest time to open global inserter: ${ success(
) }` );
}

if ( inserterSearch && inserterSearch.length ) {
// eslint-disable-next-line no-console
console.log( `
${ title( 'Inserter Search Performance:' ) }
Average time to type the inserter search input: ${ success(
round( average( inserterSearch ) ) + 'ms'
) }
Slowest time to type the inserter search input: ${ success(
round( Math.max( ...inserterSearch ) ) + 'ms'
) }
Fastest time to type the inserter search input: ${ success(
round( Math.min( ...inserterSearch ) ) + 'ms'
) }` );
}

if ( inserterHover && inserterHover.length ) {
// eslint-disable-next-line no-console
console.log( `
Expand Down
67 changes: 51 additions & 16 deletions packages/e2e-tests/specs/performance/post-editor.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
*/
import { basename, join } from 'path';
import { writeFileSync } from 'fs';
import { sum } from 'lodash';

/**
* WordPress dependencies
Expand Down Expand Up @@ -31,12 +32,15 @@ jest.setTimeout( 1000000 );

describe( 'Post Editor Performance', () => {
it( 'Loading, typing and selecting blocks', async () => {
const traceFile = __dirname + '/trace.json';
let traceResults;
const results = {
load: [],
type: [],
focus: [],
inserterOpen: [],
inserterHover: [],
inserterSearch: [],
};

const html = readFile(
Expand All @@ -60,9 +64,8 @@ describe( 'Post Editor Performance', () => {
}, html );
await saveDraft();

let i = 5;

// Measuring loading time
let i = 5;
while ( i-- ) {
const startTime = new Date();
await page.reload();
Expand All @@ -72,8 +75,6 @@ describe( 'Post Editor Performance', () => {

// Measure time to open inserter
await page.waitForSelector( '.edit-post-layout' );
const traceFile = __dirname + '/trace.json';
let traceResults;
for ( let j = 0; j < 10; j++ ) {
await page.tracing.start( {
path: traceFile,
Expand All @@ -82,7 +83,6 @@ describe( 'Post Editor Performance', () => {
} );
await openGlobalBlockInserter();
await page.tracing.stop();

traceResults = JSON.parse( readFile( traceFile ) );
const [ mouseClickEvents ] = getClickEventDurations( traceResults );
for ( let k = 0; k < mouseClickEvents.length; k++ ) {
Expand All @@ -91,6 +91,39 @@ describe( 'Post Editor Performance', () => {
await closeGlobalBlockInserter();
}

// Measure time to search the inserter and get results
await openGlobalBlockInserter();
for ( let j = 0; j < 10; j++ ) {
// Wait for the browser to be idle before starting the monitoring.
// eslint-disable-next-line no-restricted-syntax
await page.waitForTimeout( 500 );
await page.tracing.start( {
path: traceFile,
screenshots: false,
categories: [ 'devtools.timeline' ],
} );
await page.keyboard.type( 'p' );
await page.tracing.stop();
traceResults = JSON.parse( readFile( traceFile ) );
const [
keyDownEvents,
keyPressEvents,
keyUpEvents,
] = getTypingEventDurations( traceResults );
if (
keyDownEvents.length === keyPressEvents.length &&
keyPressEvents.length === keyUpEvents.length
) {
results.inserterSearch.push(
sum( keyDownEvents ) +
sum( keyPressEvents ) +
sum( keyUpEvents )
);
}
await page.keyboard.press( 'Backspace' );
}
await closeGlobalBlockInserter();

// Measure inserter hover performance
const paragraphBlockItem =
'.block-editor-inserter__menu .editor-block-list-item-paragraph';
Expand All @@ -100,7 +133,10 @@ describe( 'Post Editor Performance', () => {
await page.waitForSelector( paragraphBlockItem );
await page.hover( paragraphBlockItem );
await page.hover( headingBlockItem );
for ( let j = 0; j < 20; j++ ) {
for ( let j = 0; j < 10; j++ ) {
// Wait for the browser to be idle before starting the monitoring.
// eslint-disable-next-line no-restricted-syntax
await page.waitForTimeout( 200 );
await page.tracing.start( {
path: traceFile,
screenshots: false,
Expand All @@ -124,24 +160,25 @@ describe( 'Post Editor Performance', () => {

// Measuring typing performance
await insertBlock( 'Paragraph' );
i = 200;
i = 20;
await page.tracing.start( {
path: traceFile,
screenshots: false,
categories: [ 'devtools.timeline' ],
} );
while ( i-- ) {
// Wait for the browser to be idle before starting the monitoring.
// eslint-disable-next-line no-restricted-syntax
await page.waitForTimeout( 200 );
await page.keyboard.type( 'x' );
}

await page.tracing.stop();
traceResults = JSON.parse( readFile( traceFile ) );
const [
keyDownEvents,
keyPressEvents,
keyUpEvents,
] = getTypingEventDurations( traceResults );

if (
keyDownEvents.length === keyPressEvents.length &&
keyPressEvents.length === keyUpEvents.length
Expand All @@ -163,31 +200,29 @@ describe( 'Post Editor Performance', () => {
.map( () => createBlock( 'core/paragraph' ) );
dispatch( 'core/block-editor' ).resetBlocks( blocks );
} );

const paragraphs = await page.$$( '.wp-block' );

await page.tracing.start( {
path: traceFile,
screenshots: false,
categories: [ 'devtools.timeline' ],
} );
for ( let j = 0; j < 10; j++ ) {
await paragraphs[ 0 ].click();
for ( let j = 1; j <= 10; j++ ) {
// Wait for the browser to be idle before starting the monitoring.
// eslint-disable-next-line no-restricted-syntax
await page.waitForTimeout( 200 );
await paragraphs[ j ].click();
}

await page.tracing.stop();

traceResults = JSON.parse( readFile( traceFile ) );
const [ focusEvents ] = getSelectionEventDurations( traceResults );
results.focus = focusEvents;

const resultsFilename = basename( __filename, '.js' ) + '.results.json';

writeFileSync(
join( __dirname, resultsFilename ),
JSON.stringify( results, null, 2 )
);

deleteFile( traceFile );

expect( true ).toBe( true );
Expand Down
1 change: 1 addition & 0 deletions packages/e2e-tests/specs/performance/site-editor.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ describe( 'Site Editor Performance', () => {
focus: [],
inserterOpen: [],
inserterHover: [],
inserterSearch: [],
};

const html = readFile(
Expand Down

0 comments on commit 5d5bc72

Please sign in to comment.