hotwired / turbo

The speed of a single-page web application without having to write any JavaScript
https://turbo.hotwired.dev
MIT License
6.56k stars 415 forks source link

Any plans to share remote data fetching between tabs (either via Websockets or HTTP) using leader election? #1092

Open feliperaul opened 7 months ago

feliperaul commented 7 months ago

I'm just now catching up with the refresh/morphing goodness in Turbo 8. Everything is very exciting!

I'm a tab freak. It's not unusual to have multiple tabs opened to the same app and I think that applies to a lot of people nowadays.

Before Turbo 8, multiple tabs would already create multiple Websockets connections for each tab that subscribes to a stream, creating an unnecessary extra burden to the backend.

With Turbo 8, I think the situation is aggravated because the tabs using the turbo refresh feature will add an extra request to the server every time an update occurs.

RxDB has dedicated a lot of work in optimizing this, via the broadcast-channel library:

Imagine we have a website which displays the current temperature of the visitors location in various charts, numbers or heatmaps. To always display the live-data, the website opens a websocket to our API-Server which sends the current temperature every 10 seconds. Using the way most sites are currently build, we can now open it in 5 browser-tabs and it will open 5 websockets which send data 6*5=30 times per minute. This will not only waste the power of your clients device, but also wastes your api-servers resources by opening redundant connections.

The solution to this redundancy is the usage of a leader-election algorithm which makes sure that always exactly one tab is managing the remote-data-access. The managing tab is the elected leader and stays leader until it is closed. No matter how many tabs are opened or closed, there must be always exactly one leader. You could now start implementing a messaging-system between your browser-tabs, hand out which one is leader, solve conflicts and reassign a new leader when the old one 'dies'. Or just use RxDB which does all these things for you.

Considering the library that does the leader-election and inter-tab communication is already extracted, maybe Turbo could benefit from that mature mechanism (which also supports fallbacks for older browsers) to bring this important optimization to the table.

It could not only manage one single WS connection to the server regardless of the # of tabs open, but it would also proxy the HTTP refresh requests and debounce them, so that if 10 tabs have the same url opened and a refresh occurs, only one HTTP GET would be sent to the server and then it's response distributed to the other 9 tabs.

Is this something that would be considered?

jorgemanrubia commented 7 months ago

Thanks for the insight @feliperaul, this is an interesting one. I can say this is not in our list of priorities. I'd love to gather more evidence this would be a good idea.