Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Fix the driver behind crashes, sound loss and screen glitches3Repair Windows errors before they cause bigger problemsFor small, fire-and-forget data sent as a page is leaving, use navigator.sendBeacon() from a visibilitychange handler—not an ordinary asynchronous fetch() in beforeunload. A normal fetch may not finish before the document is discarded, and the exit event itself may never run. If you need a response or more control over the request, use fetch() with keepalive: true, while recognizing that it cannot make page-exit delivery certain.
Why a fetch in beforeunload can be lost
When a document is being discarded, the browser may stop its JavaScript context before a regular asynchronous request finishes. That makes an ordinary fetch() launched from beforeunload an unreliable way to send final analytics or diagnostics; it is not guaranteed to be sent or completed. MDN’s Beacon API guidance describes the problem with end-of-page requests, and the W3C Beacon specification sets out the intended approach for queued requests during page dismissal.
As an Amazon Associate I earn from qualifying purchases.
Changing the request mechanism does not solve every failure mode: beforeunload and unload are not dependable lifecycle hooks. MDN also cautions that pagehide may not fire in many situations, especially on mobile. A browser can suspend or terminate a backgrounded page without giving its script the callback you expected. MDN recommends using visibilitychange for end-of-session telemetry.
Send small end-of-session data with sendBeacon()
Listen for the document becoming hidden and queue the payload with navigator.sendBeacon():
#1 Best Overall
document.addEventListener("visibilitychange", () => {
if (document.visibilityState === "hidden") {
const queued = navigator.sendBeacon("/log", analyticsData);
if (!queued) {
// The browser did not queue this beacon.
}
}
});
sendBeacon(url, data) queues a small asynchronous HTTP POST without holding up the next navigation. Its payload may be a string, Blob, FormData, URLSearchParams, or a supported buffer or view type. MDN documents a limit of 64 KiB (65,536 bytes) for queued data. Keep the payload small, and do not make a beacon the only copy of information that must be saved reliably.
The method returns a boolean: true means the user agent accepted the data into its queue, not that the server received or processed it. The API does not provide a response to the page. If the return value is false, the browser did not accept the beacon into the queue; the page still cannot use that moment to wait for a server acknowledgement.
Rank #2
When fetch({ keepalive: true }) is the better fit
Use a keepalive fetch when the request needs a method other than POST, custom request properties, or access to a response. For example:
The Tool Desk
Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →fetch("/log", {
method: "PUT",
body: analyticsData,
keepalive: true
});
keepalive: true is designed for requests that may outlast the page, and gives more request control than sendBeacon(). It does not guarantee that the code initiating the request will run before the browser terminates the page, nor does it turn page-exit delivery into a reliable transaction. For lifecycle tradeoffs, see MDN’s discussion of deferred fetch.
| Approach | Request control | Can read response? | Page-dismissal behavior |
|---|---|---|---|
fetch() without keepalive |
Methods and request options supported by Fetch | Yes, if the request completes | A regular asynchronous request may not complete as the document is discarded. |
navigator.sendBeacon() |
POST with a payload; no response access | No | Queues small data asynchronously without delaying navigation; queued data is limited to 64 KiB. |
fetch() with keepalive: true |
More control, including non-POST methods and request properties | Yes, if the request completes and the page can handle it | Designed to allow a request to outlast the page, but cannot ensure the lifecycle callback runs. |
Choose a lifecycle trigger that can run before dismissal
For ordinary end-of-session telemetry, treat visibilitychange to hidden as the signal to queue data. Do not wait for beforeunload or unload to make the request. If you need a fallback for browsers without visibilitychange, MDN notes that pagehide is compatible with the back/forward cache, but it remains unreliable on mobile. A lifecycle event is an opportunity to send—not a delivery guarantee.
Do not substitute synchronous XHR, navigation-blocking prompts, or busy loops. Those approaches delay navigation and harm responsiveness rather than fixing the underlying uncertainty.
Quick Recap
Best Value
Rank #4
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.
Quick wins for a faster PC:
Scan for outdated or missing drivers - takes under a minuteDriver Scan →Clear out junk files and repair common Windows errorsFree Scan →




