I’m working on a Phoenix LiveView application and noticed an annoying behavior on mobile devices: whenever users switch tabs and return to the app, the entire page reloads even if it was fully loaded before. This happens consistently on both iOS and Android browsers.
The Issue
User loads a LiveView page on mobile
User switches to another browser tab or app
User returns to the original tab
The socket reconnects and triggers a full page reload, losing scroll position and any client-side state
This creates a poor user experience, especially on slower connections where users have to wait for the entire page to reload.
Our implementation uses standard LiveSocket configuration:
let liveSocket = new LiveSocket("/live", Socket, {
timeout: 60000,
params: { _csrf_token: csrfToken },
// ... standard configuration
});
We don’t have any visibilitychange or pageshow/pagehide event handlers
Is this the default Phoenix LiveView behavior? Does LiveView intentionally trigger a full remount when reconnecting after tab switches?
Here a potential solution I’m considering
// Detect tab visibility changes
document.addEventListener("visibilitychange", () => {
if (document.hidden) {
// Gracefully disconnect?
liveSocket.disconnect();
} else {
// Reconnect without full reload?
liveSocket.connect();
}
});
But I’m unsure if this is the right approach or if it might cause other issues…
This one works fine for me, as well as older projects I did with older versions of liveview (it was pre-1.0).
I’m not sure when this was introduced, but it doesn’t feel intentional and is probably a bug worth reporting?
I’m having the same issue, in all my liveview applications. But it’s so hard to reproduce intentionally, as you need to keep the tab in the background for “long enough”.
It’s really jarring, as when it happens the reconnect takes a long while, much longer than when first visiting.
My guess is that the socket disconnects after a while. Then when switching tabs, the socket reconnect is already in the backoff phase and that’s why it takes a long time to reconnect?
But I’ve also noticed that after the socket reconnected, it immediately does a full refresh as well.
So yeah, any hints on how to solve this are greatly appreciated! Also, how do you even debug this?