最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

How to detect when browser throttles timers and websockets disconnection after a user leaves a tab or turns off the screen? (jav

programmeradmin1浏览0评论

Context

A game shipped as a progressive web app which has timers (setTimeout, setInterval) and websocket connections to get real-time communication.

What is happening

Everything is fine as long as the user stays in the app. But when the user goes to another tab, or another app or turns off the screen (in case of mobile), it becomes a "hellish unknown world".

  • Websockets may or may not become "paused" or "turned off"
  • Timers look like they are being throttled or debounced.

This behaviour seems to depend on browsers and platform and, maybe, even depend on the particular user behaviour. I guess browsers and OS have their own lifecycle / mechanisms to save battery and/or computation.

When the user comes back, the app is in an unknown state and I am struggling to restore the state properly.

Regarding websockets I have auto-reconnection with socket.io and reconnecting-websocket but it's not enough to solve everything.

Looking for answers

  • What are the "lifecycles" of the different browsers regarding these? Is this documented? When do they decide to turn off and throttle?
  • What do they do exactly to websockets? Browsers just disconnect them?
  • What do they do exactly to timers? They throttle them or debounce them or something else?
  • What happens to javascript execution in general? Paused / destroyed / throttled?
  • Is there a way to hook into some kind of browser lifecycle event when it's going to turn things off? The only thing I could find might be the visibility API
  • Is there a way to artificially reproduce this behaviour to be able to test solutions? It's especially hard on desktop. Websockets can't be turned off and chromium developers don't seem in a hurry to help an issue from 2014(!): websockets not included when using connection throttling

  • Regardless of the above, is there a pragmatic cross-browser solution to detect / solve this problem? (for example from experience, Firefox on desktop seems to behave completely different compared to Chrome, and an iPhone will disconnect far more often than an Android)

Related Links

  • Safari dropping web socket connection due to inactivity when page not in focus

Context

A game shipped as a progressive web app which has timers (setTimeout, setInterval) and websocket connections to get real-time communication.

What is happening

Everything is fine as long as the user stays in the app. But when the user goes to another tab, or another app or turns off the screen (in case of mobile), it becomes a "hellish unknown world".

  • Websockets may or may not become "paused" or "turned off"
  • Timers look like they are being throttled or debounced.

This behaviour seems to depend on browsers and platform and, maybe, even depend on the particular user behaviour. I guess browsers and OS have their own lifecycle / mechanisms to save battery and/or computation.

When the user comes back, the app is in an unknown state and I am struggling to restore the state properly.

Regarding websockets I have auto-reconnection with socket.io and reconnecting-websocket but it's not enough to solve everything.

Looking for answers

  • What are the "lifecycles" of the different browsers regarding these? Is this documented? When do they decide to turn off and throttle?
  • What do they do exactly to websockets? Browsers just disconnect them?
  • What do they do exactly to timers? They throttle them or debounce them or something else?
  • What happens to javascript execution in general? Paused / destroyed / throttled?
  • Is there a way to hook into some kind of browser lifecycle event when it's going to turn things off? The only thing I could find might be the visibility API
  • Is there a way to artificially reproduce this behaviour to be able to test solutions? It's especially hard on desktop. Websockets can't be turned off and chromium developers don't seem in a hurry to help an issue from 2014(!): websockets not included when using connection throttling

  • Regardless of the above, is there a pragmatic cross-browser solution to detect / solve this problem? (for example from experience, Firefox on desktop seems to behave completely different compared to Chrome, and an iPhone will disconnect far more often than an Android)

Related Links

  • Safari dropping web socket connection due to inactivity when page not in focus
Share Improve this question edited Mar 29, 2020 at 11:48 Kev asked Mar 19, 2020 at 13:23 KevKev 5,4527 gold badges36 silver badges55 bronze badges 2
  • 1 This is just a draft wicg.github.io/page-lifecycle. – Sam R. Commented Mar 27, 2020 at 4:38
  • Related: developer.chrome.com/blog/timer-throttling-in-chrome-88 – Etienne Martin Commented Jul 1, 2021 at 22:11
Add a comment  | 

2 Answers 2

Reset to default 8

Not exactly sure, but you could use service workers. As much as I know, they run in background even if your tab is not opened and get terminated if your tab closes.

Btw. lifecycles of browser tabs seem to be different on every browser, since every browser handles it different. From what I see the browser can freeze tabs if it needs more memory for other things.

Here is the docs from Chrome.

I remembered that there are some events, like onload that tell you if a user has left or reopened the tab. You could use these event to reconnect etc..

I would give different advice regarding how to design your app. From what I understand your intention is to add more logic in order to understand if the user is no longer active in the browser. This entails a different problem which is browser specifics to implement that logic. With that in mind, I would instead invest in have better error handling, both in the server and client.

Errors won't be browser-specific. Handling those will make your app more resilient and agnostic to browser changes, that could eventually change, let's say, the way they hibernate a tab, any other feature that a vendor might implement in the future.

This is an idea that you can find in services architecture, but the same pattern applies to any web-app. You might want to look for Design-for-Fail concepts:

Complexity makes it infeasible to assume robustness on the part of the systems upon which one relies. Instead, one needs to design systems and applications at any given layer in the IT stack-based to assume the possibility of failure at lower levels. Design-for-fail necessitates thinking about fault tolerance at all layers. No longer can application developers confine themselves to thinking about functionality.

https://www.oreilly.com/library/view/designing-delivery/9781491903742/ch04.html

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论