Skip to the content

Browser support for the Page Lifecycle API

Which browsers send visibilitychange, pagehide, pageshow, freeze and resume, how Chromium, Firefox and WebKit order the listeners, and the sources of each fact.

The facts on this page come from the research of the lag project on 2026-10-07 (browser support, local experiments).

The events and the properties

FeatureAPIChromiumFirefoxSafari
Page visibilityvisibilitychange, document.visibilityStateYesYesYes
Back/forward cache eventspagehide, pageshow, persistedYesYesYes
Page Lifecyclefreeze, resume, document.wasDiscarded68 (Edge 79)NoNo
Visibility-state entriesvisibility-state performance entries115NoNo
Not-restored reasonsnotRestoredReasons123 (gradual rollout)NoNo

The research gives no versions for the rows with "Yes". The tracker uses only the first three rows. It examines nothing else, thus it operates in each browser of the table.

What the tracker does in each engine

  • Chromium sends all seven events. A page becomes frozen at freeze or at a pagehide with persisted.
  • Firefox and Safari do not send freeze and resume. There, a page becomes frozen only at a pagehide with persisted set to true.
  • All engines send pageshow with persisted set to true for a restore from the back/forward cache.

The listener order on window and on document

Experiment E1 measured the order of a bubble listener that the page added first and a capture listener that it added second:

TargetChromium 145Firefox 146WebKit (Safari 26.0 build)
window, custom EventBubble firstCapture firstCapture first
window, pagehideBubble firstCapture firstCapture first
document, custom EventCapture firstCapture firstCapture first
document, Event with bubbles: trueCapture firstCapture firstCapture first
document.bodyCapture firstCapture firstCapture first

On window, Chromium starts the listeners in the order of their registration. Capture phase and listener order tells what this means for an exporter, and how the export phase solves it.

Notes on the engines

  • Before Safari 14 and 14.1, visibilitychange did not bubble to window, and it did not occur when the user went to another page. The tracker listens for visibilitychange on document, and it also uses pagehide.
  • Chrome deprecated the unload event in steps. From Chrome 154 (2026-09-22), Chrome does not start unload listeners. The tracker does not use unload or beforeunload.
  • Chrome freezes pages in the back/forward cache, in collapsed tab groups, and in hidden tabs that use much CPU time (Energy Saver, desktop, from Chrome 133, gradual rollout). On Android, it freezes background pages after 5 minutes, and after 1 minute from Chrome 139.
  • A prerendered document is hidden until its activation.
  • No web event tells a page that the operating system goes to sleep. A locked screen usually makes the page hidden, but not on each platform.
  • A visibility-state entry with startTime 0 gives the first state of the page in Chromium. Thus a script that loads late can find out if the page was hidden before.

The focus of the document

The tracker uses document.hasFocus() to choose between active and passive. Without document.hasFocus(), for example in a simulated document, the tracker uses active for a visible page.

Sources

page-lifecycle-tracker

A TypeScript library for the Page Lifecycle API, under the MIT license. It came from lag, a monitor of the lag of the main thread of the browser.

An AI model (Claude, from Anthropic) wrote most of the text and the code of this site, under the direction of the author. The tests and an STE linter examine them.