Reputation: 21
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
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