I’ve been using liveview for a form. Sometimes the page keeps on refreshing, even if the user is typing something. It looks like it happens every 15s. here are an example in the logs
Asking the user directly he says that the page keeps on refreshing and clearing his input.
I was thinking that perhaps it was due to a bad network connection (and maybe that is), but that last occurence has been happening for somebody in the UK, and the server is in Germany.
I’m wondering how to debug this further.
Here is what I have tried so far
I can’t reproduce this consistently, it only happens for some users, sometimes. It looks like a heisenbug. I’ve tried opening an issue on liveview directly, but it was closed saying I don’t have a way to reproduce it.
I’ve checked the server load, it’s below 25% (CPU and memory both).
I’ve checked that the assets loaded on the page are not too heavy (just in case).
I’m not sure how to debug this further. Perhaps, liveview is waiting for an acknowledgement message from the client’s browser, and if it fails to receive it, it will trigger a reload.
I’m wondering if this ever happened to anybody else using liveview with forms.
Do you have more information from the user?
Which browser, OS and version?
Anything interesting happening in the browser console logs or the network tab?
Perhaps there’s something between the user and your server dropping idle connections too aggressively? You could try passing a shorter value to heartbeatIntervalMs when creating the socket, it’s documented here.
Let us know if heartbeatIntervalMs helped. I’m also planning to create small site with LiveView so I’m interested to hear about your results. I read that its default is 30s meaning 30000 ms and I feel that it’s bit high, I would try something like 5000 ms.
I tried quite hard at finding anything that references those things in liveview itself, but didn’t get to anything.
Here is my understanding. Since the idle timeout is already set at 10s, then there is nothing to do there. The only thing that needs to be changed would be the heartbeatIntervalMs. Here is how I went about it. In my app.js where you define the liveview, this is what I have
let liveSocket = new LiveSocket("/live", Socket, {
dom: {
onBeforeElUpdated(from, to) {
if (from.__x) {
window.Alpine.clone(from.__x, to);
}
},
},
params: {
_csrf_token: csrfToken,
},
hooks: Hooks,
heartbeatIntervalMs: 5000,
});
(the dom thing is coming from alpinejs intergration. I just deployed that to production, I’ll check how that works and if this has any impact.)
in the official doc it says that all options except a couple will be passed to the socket constructor
it’s true that opts are passed. Look at the last line in this code.
export class LiveSocket {
constructor(url, phxSocket, opts = {}){
this.unloaded = false
if(!phxSocket || phxSocket.constructor.name === "Object"){
throw new Error(`
a phoenix Socket must be provided as the second argument to the LiveSocket constructor. For example:
import {Socket} from "phoenix"
import {LiveSocket} from "phoenix_live_view"
let liveSocket = new LiveSocket("/live", Socket, {...})
`)
}
this.socket = new phxSocket(url, opts)
It seems to be 15s exactly. 5s of heartbeat and 10s of timeout I’m guessing.
Not sure what values to put for a really bad network. Maybe 2s of heartbeat is too much?
How about a timeout of 5s, is that unreasonable?
If connection drops after 15s it should have had at least two heartbeats with interval of 5s. Do you have any reverse proxies in front of your app? If you do maybe it is interfering with WebSocket connection?
I checked yesterday, and it happened again with Mobile Safari 14.0 on iOS 14.3
So likely not due to IE.
I’m going to try to enable the debug and see what informations I can gather from it.
Will update this thread with what I find.
Any chance it could be related to this?https://github.com/socketio/socket.io/issues/2924
It seems that if in Safari you move focus to another tab or put browser to background problems start. Some suggestions there was to use visility API and disable WebSocket while tab doesn’t have focus then reconnect when it does. But this might not help with LiveView.