question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

DBW: use navigator.sendBeacon in beforeunload/pagehide handlers

See original GitHub issue

How to check:

because user agents typically ignore asynchronous XMLHttpRequests made in an unload handler.

To solve this problem, analytics and diagnostics code have historically made a synchronous XMLHttpRequest call in an unload or beforeunload event handler to submit the data. The synchronous XMLHttpRequest blocks the process of unloading the document, which in turn causes the next navigation appear to be slower. There is nothing the next page can do to avoid this perception of poor page load performance, and the result is that the user perceives that the new web page is slow to load, even though the true issue is with the previous page.

https://developer.mozilla.org/en-US/docs/Web/API/Navigator/sendBeacon

Issue Analytics

  • State:open
  • Created 7 years ago
  • Reactions:1
  • Comments:11 (8 by maintainers)

github_iconTop GitHub Comments

1reaction
ebidelcommented, Nov 13, 2016

“uses-sendbeacon” sgtm.

For the network stuff, it looks like something clever like this could work. I didn’t realize you could dispatching beforeunload yourself works!

// Inject this into page in beforePass
const observer = new PerformanceObserver(list => {
  const xhrsRequests = list.getEntries().filter(entry => {
    // Note: fetch() does not have initiatorType - https://crbug.com/649571
    return entry.initiatorType === 'xmlhttprequest';
  });
  if (xhrsRequests.length) {
    console.log(xhrsRequests);
  }
}).observe({entryTypes: ['resource']});

// Example of page code that you should add to lighthouse-cli/test/fixtures/dobetterweb/dbw_tester.html
window.addEventListener('beforeunload', e => {
  const xhr = new XMLHttpRequest();
  xhr.open('GET', 'https://www.chromestatus.com/features', false);
  xhr.send();
});

// Inject into page in `afterPass`
window.dispatchEvent(new CustomEvent('beforeunload'));
window.dispatchEvent(new CustomEvent('pagehide'));

You could wrap the observer and dispatching part in a function that gets injected into the page. Example. You might need to play around with delaying dispatching the events.

This would’t tell you that the XHR was sync (unless you also grep the console output for the warning chrome throws when sync xhrs are used), but I don’t think it would hurt to always suggest navigator.sendBeacon for all requests made in beforeunload and pagehide handlers.

0reactions
connorjclarkcommented, Apr 25, 2019
window.addEventListener('beforeunload', function () {
   var request = new XMLHttpRequest();
request.open('GET', '/bar/foo.txt', false);  // `false` makes the request synchronous
request.send(null);

if (request.status === 200) {
  console.log(request.responseText);
}
});
VM26:1 Uncaught DOMException: Failed to execute 'send' on 'XMLHttpRequest': Failed to load 'https://developer.mozilla.org/bar/foo.txt': Synchronous XHR in page dismissal.
Read more comments on GitHub >

github_iconTop Results From Across the Web

Navigator.sendBeacon() - Web APIs | MDN
The navigator.sendBeacon() method asynchronously sends an HTTP POST request containing a small amount of data to a web server.
Read more >
Closing Chrome window not sending data with sendBeacon in ...
Currently I am using a sendBeacon within a unload event handler. FireFox: Refresh: Works; Back button: Works; Close window: Works. Chrome:.
Read more >
Using the Beacon API - Request Metrics
unload handler and try to send an AJAX request, but this was slow and unreliable. Enter the Beacon API to give us a...
Read more >
页面隐藏与卸载前, Pagehide vs visibilitychange, 页面生命周期 ...
了解更多HTTP 请求beforeunload:sendBeacon 与img.src HTTP 请求beforeunload:sendBeacon 与img.src,DBW:在beforeunload/pagehide 处理程序中使用navigator.
Read more >
Leverage useBeacon And beforeunload In Google Analytics
Then, use the sendBeacon() API to send a User Timing hit to Google Analytics without having to worry about the unload process cutting...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found