ably-js page unload behaviour

ably-js is Ably’s SDK for JavaScript environments, including the browser.
Chrome is a cross-platform web browser developed by Google. It is currently the most widely used desktop browser.

How is page unload behaviour handled by ably-js?

By default, ably-js adds a listener for the beforeunload event so that it can cleanly close a connection before a page is closed. This generally provides orderly and expected behavior. For example, connections will be seen as having closed immediately by Ably servers, and any presence members associated with a connection will be seen by all users as having left, as soon as the page is disposed.
If a connection to Ably is not explicitly closed when there is a page unload event, then the connection state is preserved by Ably for 2 minutes. Preserving connection state for 2 minutes when there is an unexpectedly dropped connection provides the opportunity for the client to reconnect and resume the connection without losing any messages.

What should I be aware of?

The beforeunload event can be unreliable in the sense that it is not guaranteed to be called under certain circumstances
It is possible for beforeunload to fire, yet the page is subsequently not disposed of. The page, or any of the libraries it loads, can legitimately handle this and cancel the navigation event that led to the page being prepared to be unloaded.
This means that the handler in ably-js that closes a connection on a beforeunload event is hazardous unless the application developer is certain that there is no case where beforeunload fires, but the page is subsequently not unloaded.
Recent releases of Chrome (version 108+), have introduced a Memory Saver feature. This is to assist with controlling the overall memory footprint of the browser. We have seen in practice that this feature has significantly increased the frequency of pages being discarded, which causes JavaScript execution to stop, and the page resources to be disposed of, without any opportunity to intercept that event.

How does Chrome's Memory Saver affect Ably connections?

With the introduction of Memory Saver, a page discard event will not cause an Ably connection to close immediately, because it doesn't fire a beforeunload event. A connection that is closed as a result of a page being discarded will still be seen by Ably as having been closed, however it will take longer to recognize that change. This is in comparison to the case of a connection that was explicitly closed following a beforeunload event.
Note that this also affects members leaving presence immediately.

What can I do about this?

If you are unsure whether or not the default beforeunload behavior is impacting connection state in an appropriate or predictable way, then our recommendations are to:
  • set closeOnUnload:false in ClientOptions when initializing the library
  • for the application to manage connection lifecycle explicitly by calling close() on the Ably realtime instance directly when it is no longer needed by the application
If you are affected by Chrome's Memory Saver functionality you can also turn it off globally, or on a site by site basis, in the browser settings.