Chrome Tab Freezing and SetTimeout/Web Workers

Chrome 79 was just released with the new tab freezing feature turned on by default. Does anyone know of a way to get around this when working with setTimeouts (or even web workers) in JavaScript?

We have some code running to check for client activity in order to facilitate a more graceful timeout/logout after a set amount of time. Unfortunately, neither of these work when the tab is in a 'frozen' state.

Any ideas?

Upvotes: 2

Views: 2652

Answers (1)

some
some

Reputation: 49582

Based on the age lifecycle api I created this class:

const pageLifecycle = new class PageLifecycle extends EventTarget {
  constructor() {
    super();
    this.state = this.getState();
    const fn = () => this.stateChange(this.getState()),
      opt = { capture: true },
      events = {
        pageshow: fn,
        focus: fn,
        blur: fn,
        visibilitychange: fn,
        resume: fn,
        freeze: () => this.stateChange("frozen"),
        pagehide: event => this.stateChange(event.persisted ? "frozen" : "terminated")
      };
    for (const [event, fn] of Object.entries(events)) window.addEventListener(event, fn, opt);
  }
  getState() {
    return document.visibilityState === "hidden" ? "hidden" : document.hasFocus() ? "active" : "passive";
  }
  stateChange(nextState) {
    if (nextState === this.state) return;
    const prevState = this.state;
    this.state = nextState;
    this.dispatchEvent(Object.assign(new Event("stateChange"), { prevState, state: this.state }));
  }
};

//--------
pageLifecycle.addEventListener("stateChange", event => console.log(`State change: ${event.prevState} >>> ${event.state}`));

You can add an event listener to it (event:stateChange), and you get one of ["active", "passive", "hidden", "frozen", "terminated"] in event.state. Check for passive and save your data. You can check event.prevState to get the previous state to determinate if you should force a check to the backend to see if the user is still loggen in.

Upvotes: 3

Related Questions