Skip to content

Commit bf2b3c5

Browse files
Send URL metric when leaving the page
This is an iteration on top of #1098 Co-authored-by: swissspidy <swissspidy@git.wordpress.org>
1 parent 5f4189d commit bf2b3c5

File tree

1 file changed

+31
-38
lines changed

1 file changed

+31
-38
lines changed

plugins/optimization-detective/detect.js

Lines changed: 31 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -325,8 +325,6 @@ export default async function detect( {
325325
/** @type {URLMetric} */
326326
const urlMetric = {
327327
url: currentUrl,
328-
slug: urlMetricsSlug,
329-
nonce: urlMetricsNonce,
330328
viewport: {
331329
width: win.innerWidth,
332330
height: win.innerHeight,
@@ -365,9 +363,24 @@ export default async function detect( {
365363
urlMetric.elements.push( elementMetrics );
366364
}
367365

368-
// TODO: Wait until the page is actually unloading.
366+
if ( isDebug ) {
367+
log( 'Current URL metrics:', urlMetric );
368+
}
369+
370+
// Wait for the page to be hidden.
369371
await new Promise( ( resolve ) => {
370-
setTimeout( resolve, 2000 );
372+
win.addEventListener( 'pagehide', resolve, { once: true } );
373+
win.addEventListener( 'pageswap', resolve, { once: true } );
374+
doc.addEventListener(
375+
'visibilitychange',
376+
() => {
377+
if ( document.visibilityState === 'hidden' ) {
378+
// TODO: This will fire even when switching tabs.
379+
resolve();
380+
}
381+
},
382+
{ once: true }
383+
);
371384
} );
372385

373386
for ( const extension of extensions ) {
@@ -379,42 +392,22 @@ export default async function detect( {
379392
}
380393
}
381394

382-
if ( isDebug ) {
383-
log( 'Current URL metrics:', urlMetric );
384-
}
395+
// Even though the server may reject the REST API request, we still have to set the storage lock
396+
// because we can't look at the response when sending a beacon.
397+
setStorageLock( getCurrentTime() );
385398

386-
// Yield to main before sending data to server to further break up task.
387-
await new Promise( ( resolve ) => {
388-
setTimeout( resolve, 0 );
399+
const body = Object.assign( {}, urlMetric, {
400+
slug: urlMetricsSlug,
401+
nonce: urlMetricsNonce,
389402
} );
390-
391-
try {
392-
const response = await fetch( restApiEndpoint, {
393-
method: 'POST',
394-
headers: {
395-
'Content-Type': 'application/json',
396-
'X-WP-Nonce': restApiNonce,
397-
},
398-
body: JSON.stringify( urlMetric ),
399-
} );
400-
401-
if ( response.status === 200 ) {
402-
setStorageLock( getCurrentTime() );
403-
}
404-
405-
if ( isDebug ) {
406-
const body = await response.json();
407-
if ( response.status === 200 ) {
408-
log( 'Response:', body );
409-
} else {
410-
error( 'Failure:', body );
411-
}
412-
}
413-
} catch ( err ) {
414-
if ( isDebug ) {
415-
error( err );
416-
}
417-
}
403+
const url = new URL( restApiEndpoint );
404+
url.searchParams.set( '_wpnonce', restApiNonce );
405+
navigator.sendBeacon(
406+
url,
407+
new Blob( [ JSON.stringify( body ) ], {
408+
type: 'application/json',
409+
} )
410+
);
418411

419412
// Clean up.
420413
breadcrumbedElementsMap.clear();

0 commit comments

Comments
 (0)