A user leaves a tab open overnight with a half-filled form in it. In the morning they click back to it and the form is empty. The tab looked exactly as they left it: right title, right favicon, sitting where it always sat.
They are not misremembering, and nothing on your page failed. Chrome threw the page away and told nobody.
What actually happened
Chrome's own description of Memory Saver: "When Memory Saver mode is enabled, Chrome will proactively discard tabs that have been unused in the background for some time." And then, "If the user revisits that tab, the page will be reloaded automatically."
The sentence that explains why the user cannot tell you any of this is the next one: "When a tab is discarded, its title and favicon still appear in the tab strip but the page itself is gone."
So there is no cue. A discarded tab is visually identical to a live one. The person clicking it has no reason to think anything happened between last night and this morning, because from where they sit, nothing did.
Why nothing in your code noticed either
This is the part worth knowing, because the instinct is to reach for a save-on-exit handler and it will not help.
The page lifecycle documentation defines the state plainly: "A page is in the discarded state when it is unloaded by the browser in order to conserve resources." Entering it fires no events, and once there, "No tasks, event callbacks, or JavaScript of any kind can run in this state."
Not beforeunload. Not pagehide. Not unload. Your handler does not run late, it does not run at all, because there is no unload from the page's point of view. There is a page, and then there is no page.
The last callback you get is freeze, which fires when the tab goes from hidden to frozen, and even that comes with a caveat: "freezable tasks in the page's task queues are suspended until the page is unfrozen". For a tab that is subsequently discarded, unfrozen never arrives, so anything you queued at freeze time and did not finish synchronously is gone with everything else.
What it costs you, which is more than one empty form
Measure this and it does not look like a browser behaviour at all. A discard followed by a return is a fresh page load, so in your analytics one person becomes two sessions, with an abandoned form in the first and a cold start in the second. The funnel reports a bounce and a new arrival. The truth is one user who never left.
That is the part that quietly skews numbers nobody is auditing: not a lost form, but a session count that includes an event the user did not cause.
The one fact that settles it
There is a flag for exactly this. Chrome again: "It is possible to detect that a tab was discarded after a user returns to it and the page is reloaded. In these situations the document.wasDiscarded property will be true."
// On load: was this page here before, and thrown away?
if (document.wasDiscarded) {
restoreDraft(sessionStorage.getItem('draft'))
analytics.track('page_load', { cause: 'tab_discard' })
}
// Last chance to write anything down.
document.addEventListener('freeze', () => {
sessionStorage.setItem('draft', currentDraft())
}, { capture: true })
sessionStorage is the right place, and the reason is worth a sentence. A discard destroys the page, not the tab: the tab keeps its slot, its title and its favicon, and sessionStorage is scoped to that tab rather than to the document in it. So it is still there on the other side. This is the one case where the per-tab store outlives the thing you would expect to outlive it.
Why this reaches you as an unreproducible report
Your own tab is focused. Focused tabs do not get discarded, so you will not see this while you are working on the page, and you will not see it in the ten minutes you spend trying to repeat it.
Meanwhile the report says "I came back and my work was gone", which sounds like a bug in your form. There is no error, no console output, nothing in your error tracker, and nothing the reporter can tell you, because the browser did not tell them either. The single piece of evidence that separates "your save is broken" from "the browser discarded the tab" is a boolean that was true for one moment in somebody else's browser, and unless something was reading it then, it is not recoverable afterwards.
Top comments (1)
hi!