socket.io
socket.io copied to clipboard
71% of Developers Socket.io WebSocket usage is not compliant with BFCache Modern browsers behaviour making page loads slower
According to HTTP Archive data, 71% of sites using socket.io (73k out of 103k sites) have BFCache not available because developers are not following the best practices to handle WebSocket connection to allow the browser to cache the page for BFCache.
I wasn't able to find any mention of suggested best practices in the documentation unfortunately.
Anyone would be open to help developers better use WebSockets connections overall?
Read more here: https://web.dev/articles/bfcache#close-open-connections
In order to make BFCache compatible the following things should happen:
- When the page is restored via BFCache, re-open the WebSocket connection at
pageshowwhenevent.persisted==true - Close the WebSocket connection using
pagehide.
Unfortunately if developers are not doing 1) and 2) Modern browsers will not be able to store the page for a future Back/Forward navigation, making Page Loads significantly slower to their users when socket.io is used.
Core Web Vitals Web Performance metrics reflects that, leading to a higher LCP (maybe CLS, depends by the site).
Doing so could have a huge impact to users browsing sites when socket.io library is used, also the library itself will not have to load if the page has been restored from the BFCache and the connection would be restored by using the pageshow method.
Similar to this issue: https://github.com/socketio/socket.io/issues/1660
Hi!
Shouldn't it be the duty of the user of the library? Something like:
const socket = io({
autoConnect: false
});
addEventListener("pageshow", (event) => {
socket.connect();
});
addEventListener("beforeunload", (event) => {
socket.disconnect();
});
Note: with the closeOnBeforeunload option set to true (defaults to false), the browser will automatically close the WebSocket connection when the beforeunload event is emitted.
Hi Damien, nice to e-meet you and thanks for your quick turn around here!
I agree with you that in theory it should be the developers using the library to use it in the proper way, but It's also likely that most of them may miss this point and sacrifice their page load performance.
Does the Socket.io documentation have a section where perhaps this practice can be suggested as best practice?
Something like, to make sure the WebSocket Connection would not prevent BFCache (that could be a big deal for Performance) make sure to call connect() on the pageshow event.
About the closeOnBeforeunload setting that you mention, is there a reason why the default is non true instead of false?
Actually, once this bug will be fixed, I would much rather suggest using pagehide instead of beforeunload for the same purpose but more reliable and less problematic event.
@darrachequesne I took a chance to rewrite the initial description because now the beforeUnload method is no longer suggested.
Chrome now handles correctly Closing WebSocket connection on pagehide.
If that's not feasible from the library POV to enforce these best practices, do you think it may be possible to suggest them somewhere?
All Back/Forward Navigations would be a lot slower without benefiting of BFCache on Modern Browsers.
@darrachequesne I've updated the description with better explainations and impacts stats, it looks like at least 71% of Sites using socket.io are using it in a non optimal way.
All of those webistes could benefit of this change if they don't have any other BFCache blocking reason.
Also, we suggest not to use beforeunload but rather pagehide to close the connection, but even if developers would use that option it would not be sufficient to make the usage compatible with BFCache.
If we assume flaky internet could also drop the WebSocket connection at any time, from my POV, the best way to go about this would be to implement this from socket.io side, because socket.io knows whether the transport mechanism is a real WebSocket or not, and putting this right into socket.io has the greatest positive impact on the ecosystem.
As Gilberto says, it would automatically improve bfcache support for any user of socket.io, with little complexity and no real breaking change if the socket is closed / re-connected on pagehide / show (because as mentioned, flaky internet could drop the connection at any time, too).
I'd even go so far as recommending to deprecate closeOnBeforeunload, as a user probably doesn't care at which exact event the WS is disconnected and rather that is disconnects when the user navigates away.
The change would be a semver major change, but it sounds worth it to me.
... or we should at least put it into the docs, into a visible spot.
Hi, just chiming in. This would have been nice to know during the integrating step in socket.io's tutorial, "Integrating Socket.IO." Maybe as a tip that references "Close open connections before the user navigates away" from web.dev, as previously mentioned?
Hi Andrew, that's a great idea, thanks for sharing, I am happy to trigger a github issue suggesting that change.