A page contains an unload-handler pattern
In the reportUnload/beforeunload handler pattern in first-party script
unload_handler_detected · Review item
This appears when a page's script text or <body> attribute matches an unload or beforeunload handler pattern, such as addEventListener('unload', …). A text match can also be code that removes a handler, such as onunload = null; it does not prove that one is registered. In desktop Chrome and Firefox, an unload listener keeps a page out of the back/forward cache, so check whether a listener is actually registered and use pagehide instead.
Severity: Notice. For review: it is a text match, which can also find comments or code that never runs.
Why it matters
web.dev's article on the back/forward cache says the most important way to optimise for it in all browsers is never to use the unload event, that desktop Chrome and Firefox make pages with an unload listener ineligible, and advises using pagehide instead and adding beforeunload listeners only conditionally.
What to do
- Look at the finding: it shows bounded examples of matching script text or body attributes, with line numbers and surrounding text where captured. The report may omit additional examples, so inspect the original scripts before making changes.
- Check whether the code runs on the page: matches in comments, strings or unused libraries do no harm.
- Replace
unloadhandlers withpagehide, and addbeforeunloadonly while there are unsaved changes.
When to leave it as it is: if the match is in a comment or in code that never runs, or it removes a handler, such as onunload = null, you can leave it.
What we read
We read the text of each crawled page's inline classic and module scripts, up to 128 KiB each, the onunload and onbeforeunload attributes of <body>, and the scripts from the page's own origin that the audit fetches. Data blocks such as JSON, and scripts from other origins, a CDN subdomain of yours included, are skipped.
A page is reported when the text matches addEventListener with unload or beforeunload, or an assignment to onunload or onbeforeunload, or when <body> has such an attribute. Nothing is run.
A page is marked as not checked when its HTML could not be read in full, its inline scripts pass the size limits, or a script from its own origin was not fetched, did not answer 200, is over 1 MiB, could not be decoded or contains null characters.
Example & evidence
Illustrative example — one line of one script, not a live audit.
https://bakery.example/js/cart.js, loaded by https://bakery.example/cart/, contains:
window.addEventListener('unload', saveCart);The captured line matches an unload listener pattern, so the page is reported with a script excerpt and line number. The check does not establish whether the line executes or registers a listener.
window.addEventListener('pagehide', saveCart);A possible correction: save the cart on pagehide.
Confirm & check again
Check for yourself: open the page in Chrome, go to another page and back, and look in the developer tools under Application, Back/forward cache, for the reason it was not restored.
Check again: Full audit — run a new audit of the site. The finding closes when the page is crawled again, every script it reads is read in full, and none matches. A script from the page's own origin that was not among the files fetched keeps the finding open.
Limits & sources
It is a text match, not a run: it also finds comments, strings and dead code, and it misses handlers set through libraries, such as jQuery's .on('unload'), or with event names held in variables. A beforeunload match does not by itself show that the page is kept out of the cache, and no cache test is made.
Confidence: Low because a text match cannot tell whether the handler is registered when the page runs.
Sources
- web.dev, Back/forward cache — says never using the unload event is the most important bfcache optimisation, that desktop Chrome and Firefox make pages with an unload listener ineligible, and advises pagehide instead. Checked 28 September 2026.
Editorial review: 1 November 2026