Browser Engineering

Page Lifecycle in Real-Time Apps: Freeze, Resume, and Lost Timers

Handle visibilitychange, pagehide, freeze, resume, and system sleep by separating hidden, frozen, and offline states and reconciling connections after wake.

The dangerous implementation is not one that never works. It is one that works in a demo and loses its boundaries under real networks and real data volume. A background tab may stop timers and JavaScript without immediately closing sockets. One delayed heartbeat is not proof of departure, and an old connection is not automatically valid after wake.

Browser capability depends on version, permission, visibility, and device policy. Use capability detection and an explained fallback instead of treating one development machine as the product contract.

Engineering boundaries and tradeoffs

List non-negotiable invariants before selecting performance knobs. Tuning can roll out gradually; identity, permission, and terminal-state rules cannot drift at runtime.

  • Track visibility, execution freeze, network reachability, and peer session as separate states.
  • Persist unfinished work and explicit stop intent before freeze without starting long asynchronous work in the event.
  • After resume, reconcile session version, heartbeat, and selected candidate pair before resuming features.

A real-time page treats suspended execution as normal. Recovery rebuilds ownership from persisted state and peer facts instead of continuing an old callback.

How it fails in production

Failure and success must share one state model. An error toast that neither releases resources nor propagates a terminal state leaves dirty work for the next recovery attempt.

  • Throttled reconnect timers wake together and create a signaling storm.
  • pagehide is treated as permanent exit, so a bfcache page revokes trust and tasks.
  • Resume keeps an old file loop while starting a new one, duplicating chunks and regressing progress.

Turn testing into a closed loop

Do not stop verification when the final action succeeds. Count side effects, measure wait time, inspect privacy, and prove the next run begins from a clean baseline.

  1. Recover after a hidden tab, system sleep, and memory freeze; every task must have one owner.
  2. Release throttled fake timers together and verify jitter plus a global reconnect cap.
  3. Return from bfcache and prove handlers, WebSockets, and analytics listeners are not duplicated.

A capability becomes maintainable when it degrades safely, repetition adds no side effects, and its signals reveal a fault before user reports do.

Put the guide to work

Open uCopy and connect two devices securely from the browser.

Start for free