mirror of
https://github.com/gosticks/wordpress-develop.git
synced 2026-06-28 22:30:04 +00:00
Build/Test Tools: Measure additional load time metrics in performance tests.
Three new metrics are being collected and reported as part of this change: - Time To First Byte (TTFB) - the time between the request for a resource and when the first byte of a response begins to arrive - Largest Contentful Paint (LCP) — the render time of the largest image or text block visible within the viewport - The difference between the two (LCP minus TTFB) Props joemcgill, flixos90, oandregal, mukesh27, youknowriad, swissspidy. Fixes #58360. git-svn-id: https://develop.svn.wordpress.org/trunk@56399 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
@@ -3,7 +3,11 @@
|
||||
*/
|
||||
const { basename, join } = require( 'path' );
|
||||
const { writeFileSync } = require( 'fs' );
|
||||
const { getResultsFilename } = require( './../utils' );
|
||||
const {
|
||||
getResultsFilename,
|
||||
getTimeToFirstByte,
|
||||
getLargestContentfulPaint,
|
||||
} = require( './../utils' );
|
||||
|
||||
/**
|
||||
* WordPress dependencies.
|
||||
@@ -15,6 +19,9 @@ describe( 'Server Timing - Twenty Twenty Three', () => {
|
||||
wpBeforeTemplate: [],
|
||||
wpTemplate: [],
|
||||
wpTotal: [],
|
||||
timeToFirstByte: [],
|
||||
largestContentfulPaint: [],
|
||||
lcpMinusTtfb: [],
|
||||
};
|
||||
|
||||
beforeAll( async () => {
|
||||
@@ -22,7 +29,9 @@ describe( 'Server Timing - Twenty Twenty Three', () => {
|
||||
} );
|
||||
|
||||
afterAll( async () => {
|
||||
const resultsFilename = getResultsFilename( basename( __filename, '.js' ) );
|
||||
const resultsFilename = getResultsFilename(
|
||||
basename( __filename, '.js' )
|
||||
);
|
||||
writeFileSync(
|
||||
join( __dirname, resultsFilename ),
|
||||
JSON.stringify( results, null, 2 )
|
||||
@@ -40,14 +49,19 @@ describe( 'Server Timing - Twenty Twenty Three', () => {
|
||||
const [ navigationTiming ] = JSON.parse( navigationTimingJson );
|
||||
|
||||
results.wpBeforeTemplate.push(
|
||||
navigationTiming.serverTiming[0].duration
|
||||
navigationTiming.serverTiming[ 0 ].duration
|
||||
);
|
||||
results.wpTemplate.push(
|
||||
navigationTiming.serverTiming[1].duration
|
||||
);
|
||||
results.wpTotal.push(
|
||||
navigationTiming.serverTiming[2].duration
|
||||
navigationTiming.serverTiming[ 1 ].duration
|
||||
);
|
||||
results.wpTotal.push( navigationTiming.serverTiming[ 2 ].duration );
|
||||
|
||||
const ttfb = await getTimeToFirstByte();
|
||||
const lcp = await getLargestContentfulPaint();
|
||||
|
||||
results.timeToFirstByte.push( ttfb );
|
||||
results.largestContentfulPaint.push( lcp );
|
||||
results.lcpMinusTtfb.push( lcp - ttfb );
|
||||
}
|
||||
} );
|
||||
} );
|
||||
|
||||
@@ -4,7 +4,11 @@
|
||||
const { basename, join } = require( 'path' );
|
||||
const { writeFileSync } = require( 'fs' );
|
||||
const { exec } = require( 'child_process' );
|
||||
const { getResultsFilename } = require( './../utils' );
|
||||
const {
|
||||
getResultsFilename,
|
||||
getTimeToFirstByte,
|
||||
getLargestContentfulPaint,
|
||||
} = require( './../utils' );
|
||||
|
||||
/**
|
||||
* WordPress dependencies.
|
||||
@@ -16,15 +20,22 @@ describe( 'Server Timing - Twenty Twenty One', () => {
|
||||
wpBeforeTemplate: [],
|
||||
wpTemplate: [],
|
||||
wpTotal: [],
|
||||
timeToFirstByte: [],
|
||||
largestContentfulPaint: [],
|
||||
lcpMinusTtfb: [],
|
||||
};
|
||||
|
||||
beforeAll( async () => {
|
||||
await activateTheme( 'twentytwentyone' );
|
||||
await exec( 'npm run env:cli -- menu location assign all-pages primary' );
|
||||
await exec(
|
||||
'npm run env:cli -- menu location assign all-pages primary'
|
||||
);
|
||||
} );
|
||||
|
||||
afterAll( async () => {
|
||||
const resultsFilename = getResultsFilename( basename( __filename, '.js' ) );
|
||||
const resultsFilename = getResultsFilename(
|
||||
basename( __filename, '.js' )
|
||||
);
|
||||
writeFileSync(
|
||||
join( __dirname, resultsFilename ),
|
||||
JSON.stringify( results, null, 2 )
|
||||
@@ -42,14 +53,19 @@ describe( 'Server Timing - Twenty Twenty One', () => {
|
||||
const [ navigationTiming ] = JSON.parse( navigationTimingJson );
|
||||
|
||||
results.wpBeforeTemplate.push(
|
||||
navigationTiming.serverTiming[0].duration
|
||||
navigationTiming.serverTiming[ 0 ].duration
|
||||
);
|
||||
results.wpTemplate.push(
|
||||
navigationTiming.serverTiming[1].duration
|
||||
);
|
||||
results.wpTotal.push(
|
||||
navigationTiming.serverTiming[2].duration
|
||||
navigationTiming.serverTiming[ 1 ].duration
|
||||
);
|
||||
results.wpTotal.push( navigationTiming.serverTiming[ 2 ].duration );
|
||||
|
||||
const ttfb = await getTimeToFirstByte();
|
||||
const lcp = await getLargestContentfulPaint();
|
||||
|
||||
results.timeToFirstByte.push( ttfb );
|
||||
results.largestContentfulPaint.push( lcp );
|
||||
results.lcpMinusTtfb.push( lcp - ttfb );
|
||||
}
|
||||
} );
|
||||
} );
|
||||
|
||||
@@ -21,13 +21,58 @@ function median( array ) {
|
||||
* @return {string} Result file name.
|
||||
*/
|
||||
function getResultsFilename( fileName ) {
|
||||
const prefixArg = process.argv.find( ( arg ) => arg.startsWith( '--prefix' ) );
|
||||
const fileNamePrefix = prefixArg ? `${prefixArg.split( '=' )[1]}-` : '';
|
||||
const prefixArg = process.argv.find( ( arg ) =>
|
||||
arg.startsWith( '--prefix' )
|
||||
);
|
||||
const fileNamePrefix = prefixArg ? `${ prefixArg.split( '=' )[ 1 ] }-` : '';
|
||||
const resultsFilename = fileNamePrefix + fileName + '.results.json';
|
||||
return resultsFilename;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns time to first byte (TTFB) using the Navigation Timing API.
|
||||
*
|
||||
* @see https://web.dev/ttfb/#measure-ttfb-in-javascript
|
||||
*
|
||||
* @return {Promise<number>}
|
||||
*/
|
||||
async function getTimeToFirstByte() {
|
||||
return page.evaluate( () => {
|
||||
const { responseStart, startTime } =
|
||||
performance.getEntriesByType( 'navigation' )[ 0 ];
|
||||
return responseStart - startTime;
|
||||
} );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Largest Contentful Paint (LCP) value using the dedicated API.
|
||||
*
|
||||
* @see https://w3c.github.io/largest-contentful-paint/
|
||||
* @see https://web.dev/lcp/#measure-lcp-in-javascript
|
||||
*
|
||||
* @return {Promise<number>}
|
||||
*/
|
||||
async function getLargestContentfulPaint() {
|
||||
return page.evaluate(
|
||||
() =>
|
||||
new Promise( ( resolve ) => {
|
||||
new PerformanceObserver( ( entryList ) => {
|
||||
const entries = entryList.getEntries();
|
||||
// The last entry is the largest contentful paint.
|
||||
const largestPaintEntry = entries.at( -1 );
|
||||
|
||||
resolve( largestPaintEntry?.startTime || 0 );
|
||||
} ).observe( {
|
||||
type: 'largest-contentful-paint',
|
||||
buffered: true,
|
||||
} );
|
||||
} )
|
||||
);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
median,
|
||||
getResultsFilename,
|
||||
getTimeToFirstByte,
|
||||
getLargestContentfulPaint,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user