3.143 ways to synchronize data across documents - HTTP 203
Вставка
- Опубліковано 24 сер 2024
- Jake chats to Surma about six ways you can synchronise data between documents, but some of them don't work all the time, so a complex and scientific scoring system is needed.
window.postMessage → goo.gle/3c0v4Kz
Surma mentioned his comlink library again so I guess we have to link to it → goo.gle/3hvasLN
EventSource → goo.gle/3ityojV
Web Locks → goo.gle/3mmCI6I
The storage event → goo.gle/3iuPcHk
BroadcastChannel → goo.gle/35xBz6n
Service worker clients API → goo.gle/3mh7oGx
IDB observers → goo.gle/3hq3O9D
Other videos in the series → goo.gle/2wneQLl
Subscribe to Google Chrome Developers here → goo.gle/Chrome...
Also, if you enjoyed this, you might like the HTTP203 podcast! → goo.gle/2y0I5Uo
Yep, the sum is correct.
phew
came down to the comments just to check lol. At least they didn't have a typo like they did in the Squoosh.app episode.
4:11 | window.postMessage (needs window reference of another window, e.g. via window.open) | Score: 0.248
5:57 | EventSource (HTTP event stream, cross-device) | Score: 0.492
8:30 | window's localstorage change event (no message to current window) | Score: 0.763
10:33 | Broadcast channel (channel->other same name channels; no safari support) | Score: 0.635
11:39 | Service worker (window->worker->all windows) | Score: 1
13:06 | IndexedDB Observers (experimental) | Score: 0.005
13:37 Butterflies in my chest-- genuine feeling of joy
13:41 Oh, maybe some little issue
13:42 Crushing sadness and feeling betrayed
With my user hat on - please don't over-use this kind of thing. Sometimes I will open another tab precisely because I want one to stay in its current state, for later reference. The examples mentioned in the video sound fine to me, but taking this kind of technique to the extreme could just be annoying to the user.
The existence of such technology does not really mean that it should be integrated on each site on the web
6:26 you also run into maximum connections per origin limits when using EventSource over HTTP/1.1, so if you have >6 tabs open then at least one won't be able to create an EventSource. (This is mostly fixed with HTTP/2+)
see stackoverflow.com/questions/16852690/sseeventsource-why-no-more-than-6-connections
the math checks out:
0.248+0.492+0.763+0.635+1+0.005 = 3.143
my reputation is safe
Yeah but can someone check if this guy's check cheks out?
Waiting for observers to be implemented in Indexed DB!! Also there is an Observable in DixieJs(an idb wrapper) if anyone is interested.
Thanks for the scientifically-proven and methodological scores ❤️
That was really interesting. Perhaps, the best among 2020 videos
Jake you chose a very interesting topic to discuss. I appreciate it :)
Service worker's are fiddly and service worker messaging is even more fiddly. As for the observers discussed at the end, that's a really nice pattern, I like to use that with a Websocket to a server that stores the state, but it would of course be nice if it didn't require a server.I didn't know about the localStorage listener, thanks!
Great show!
correct sum, no worries
gone not forgotten 6:18 ❤❤❤
What happened to him?
There is a feature request bug for BroadcastChannel in Safari: bugs.webkit.org/show_bug.cgi?id=161472. It’s currently blocked by a spec issue around partitioning: github.com/whatwg/html/issues/5803.
It works on Safari now (since march 2022)
1:53 Joy-Con 👀
Hurrar - you guys are getting your flow back
Wait. Did we lose it?
It’s looked a little ‘awkward’ vs when you guys are in the studio :)
any updates on IDBObserver? Not finding much on it and wondering if it is stalled ...
If you have server data to sync, i really like web sockets for that; keeps all instances on all devices synchronized.
It works pretty much the same as EventSource in terms of synchronising capability.
i do not think i can handle the thumbnail being a mirror of the actual video
Firefox the best browser ever
BroadcastChannel is really easy to polyfill in Safari and older browsers, for those who aren't aware :)
Via what mechanism?
@@jakearchibald I guess we'll never know :(
😂😂😂 thank you for you show.
IDBObserver would be a great solution to replace RxDB
I'm missing SharedWorker in this episode!
Well, postMessage should summarize it. And it's mentioned in BroadcastChannel.
BroadcastChannel should have a better score nowadays, given its support.
Isn't matchAll unsupported on Safari though? Which means that the workers broadcast method will not work on Safari? Please correct me if I am wrong
What do you think about accessiblity ? Section 501 for example.
Sounds good to me
Local storage ?
if you want to sync tabs across sub domains, you will have to create a JavaScript cookie and do pooling on it. YIKES IK.
I don’t know any other way other than going server side.
I would use s and postMessage for that. Avoids polling.
Who can we lobby to get them working on the ID Bob Server?
You mention that storage event is triggered when session storage is changed, but I believe session storage is not shared between different windows and the event does NOT trigger
No, we are talking about the storage event in the context of LocalStorage, not SessionStorage.
Yep. But also, a page and same origin s will share session storage.
ahh the beauty of the web :(
the local storage thing, you said that you can't store objects, but you could just stringify JSON object, correct?
Yep, but that comes with all the limitations of JSON.
@@jakearchibald for example?
@@riddixdan5572 compared to structured cloning, JSON cannot store: circular references, BigInt, Date, RegExp, ArrayBuffer, any of the ArrayBufferViews, Map, Set, Error, ImageData, ImageBitmap, Blob, File… there are probably more I'm forgetting.
@@jakearchibald Hmh, fair enough, but there are always libraries that can imitate it somewhat. but yeah, probably not everything, I guess circular reference would be the easiest to imitate. Can't say the same for other examples you brought tho.
@@riddixdan5572 Oh yeah you can make your own serialisation format if you must. But why not use one of the other storage systems that does all that for you?
Hi, thanks for this video!
We solved the task of synchronizing tabs through service worker, but we came across the fact that sw periodically falls asleep and does not respond to messages from its customers. Please tell me how to proceed in this case and is the estimate of 1.000 correct?
We started using shared workers for synchronization, and it has proven itself perfectly
Sending the service worker a message via fetch or postMessage should always wake it up. If you've found a case where it doesn't, it's a bug. However, if you're expecting the service worker to stay awake when it isn't doing anything… that isn't what it's designed for.
@@jakearchibald No, we do not expect and do not want the worker service to always be in an active state, however, we hoped that the postMessage message from the tab (his client) would wake him up.
Moreover, this behavior is very difficult to catch. Anyway, we switched to shared workers, please tell me how much better this solution is.
Or is it better to deal with the service worker after all?
I like the service worker because it keeps the list of clients always up to date. In turn, in the shared worker, you need to monitor the customers yourself
@@airmust2265 the service worker should definitely wake up on postMessage. Shared worker is good too, but not supported on mobile
@@jakearchibald understood thanks! I will also experiment with the service worker, I will try to understand why he does not come to life in me
I can't find any mention on the web that Safari on IOS supports the client API . Does clients.MatchAll work with it? see at 12:06 - so why does this method score 1.000
I'm pretty sure it does
I mean, if it doesn't, then I've messed up my scoring
@@jakearchibald I spent yesterday building a service worker and then seeing if it would work on a Macbook Air and an iPad and it appears to work fine (other CSS problems but ...). The way I retrieve this data is by actually adding to my "api" name space a "service" section where the service worker responds and never passes the request to my server.
```
const api = /^\/api\/(service|config|session|profile|approve|gadm)\/(\w+)|(\d+)\/(admin|user)\/(\w+)$/i;
self.addEventListener('fetch', (event) => {
const requestURL = new URL(event.request.url);
if (/^\/api\//i.test(requestURL.pathname)) {
//We have an api call, so deal with it appropriately
const matches = api.exec(requestURL.pathname);
if (matches === null) {
//let the browser do its own thing
} else {
switch (matches[1]) {
case 'service':
//service worker request , lets do it
switch(matches[2]) {
case 'tab':
event.respondWith(
self.clients.matchAll({includeUncontrolled: true}).then(clients => new Response(clients.length.toString(),{status: 200, headers: {
'Cache-Control': 'no-cache',
'Content-Type': 'text/plain; charset=US-ASCII',
} })));
break;
default:
event.respondWith(new Response('', { status: 404 }));//unknown so send a 404
}
break;
case 'config':
...
```
8:46 Well, you can store objects as json tho
Emrah ATILKAN You can
Only a very specific subset of objects. You can have cyclic structures in JavaScript, but that doesn't translate to JSON. JSON can't handle Maps, Sets, ArrayBuffer/ArrayBufferViews, classes, prototypes... lots of things can get lost when stringifying.
Surma Exactly, and this should be enough for most use cases. Needing to store abstract objects on the client side is a pretty rare scenario. And in some cases you can prepare complex object(s) before the "stringification". But I get your point!
Emrah ATILKAN Well it is still a JSON String though but technically not an object anymore, that’s true. Nevertheless you are still able to store objects, just not directly as objects while being in the storage. Got me there.
you forgot websocket... for every user create a channel in backend and broadcast to all instances
I guess you'd be doing about the same as SSE
@@sjorsborsoborsobors yeah, the only difference is it isn't broadcast only
@@sjorsborsoborsobors yea, almost the same in terms of pros and cons.
Clappy time XD
You forgot websocket
They were talking about offline ways
It works pretty much the same as EventSource in terms of synchronising capability.
@@jakearchibald can you use websockets to communicate between documents directly?
@@wtho nah
Https 3143
wait who is gone but not forgotten?
I forgot.