3.143 ways to synchronize data across documents - HTTP 203

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
JAKE: It's going to be good. It's going to be great. SURMA: It's going to be great. Yeah, where's the-- you told me to be more euphoric. Come on, let's-- JAKE: Well-- SURMA: --get the energy up. JAKE: --this is not broadcast. This is, you know-- SURMA: Oh. JAKE: OK, here comes-- here comes clappy time. 3, 2, 1-- [CLAP] [MUSIC PLAYING] So OK-- SURMA: So. JAKE: --lists of things are pure clickbait, right? It works, doesn't it, when you say, like-- SURMA: Oh, you mean like, the 10 things that you can do to be a rich-- number four will blow your mind. JAKE: Yeah, and like, that stuff, I know it's clickbait, but it still works on me. I can't-- I just can't stop myself. So I thought, I'm going to-- I want to get in on that tasty, tasty click action. So this is 3.143 ways to synchronize across documents. I'm actually going to talk about six things, but-- SURMA: This is annoyingly far off of pi. Like, couldn't you have made it 3.141? JAKE: Yeah, well, no. No, I decided not to. But I-- that-- do you know what, I noticed that exact same thing as well. And that did bug me. And I feel-- SURMA: But also, I like that you never use this font. You used this as your clickbait font, I presume. JAKE: Yeah. Yeah, and it's the only time I'm going to be using it in this presentation as well. So enjoy it. SURMA: Good. JAKE: Enjoy it right now. Yeah, I used some decimals, because I'm not-- of the things that I'm going to show, I'm not sure all of them count as one complete way. So I've docked a few points here and there. So OK-- SURMA: Well, when doing clickbait, at least do it fairly. JAKE: Exactly. Yeah, I do have some principles-- some. So be prepared for a shock. Did you know-- SURMA: Mm-hmm? JAKE: --that you can have multiple tabs open to a page? SURMA: Dun-da-da. JAKE: Mm, I know. SURMA: It's actually really annoying. Because whenever you write your service worker update code, that's the case that makes everything a lot harder. JAKE: Yes. Well, not just that, it's also the overlap between one page refreshing. There's a kind of time when both pages are somewhat alive. Or certainly, the request for the new page is going out while your page-- anyway, topic for another day. The thing I wanted to talk about is page state. Because while some state is in your page, but some application-level state is across those tabs-- like login state, right? You log in in one tab. You would now be expected to be logged in in another tab. But quite frequently, a lot of sites don't do anything about this. SURMA: No, I think barely any site-- I don't think Google sites do that. JAKE: Well, that's-- shame on them, I say. And this is worse for single-page apps. Because in a multi-page app, your next navigation is going to pick it up, right? SURMA: Yeah. JAKE: But in a single-page app, it might be around a lot longer. So these differences in state are going to become more and more noticeable the longer two tabs are alive. There's also client side state stuff. Like, if you've got a dark mode toggle on your site, is that per page? Or is that per-- for your application? There's this. So remember this, when we built the-- SURMA: I remember this. JAKE: --dev server website? SURMA: We wrote this. JAKE: I was really proud of this. Because this is the one thing I really wanted from any other global event. And so it's, at times, untoggled. Like, tell me the times where I am, or tell me the times where the event is. Because if you're going to the event, you want to know-- you know, it's San Francisco time. SURMA: When do I have to get up? JAKE: Exactly. And if you're watching at home, again, when do I have to get up? It's probably going to be a less sociable time. SURMA: Or how long do I have to not go to sleep? JAKE: Yes, that is-- that was mainly the difference. So yeah, you want-- if you, in one tab, change the time zone-- because this is going to be used in multiple pages. You want it to be updated everywhere. So how do we do this kind of stuff? SURMA: Did we do that? JAKE: Yeah. Yeah, I did. SURMA: Oh, didn't know. JAKE: And we'll talk about-- SURMA: That's cool. JAKE: --the way I did it as well. Let's go through a number of different ways of doing stuff like this. Here's number one. There you go. Post message-- job done. That's one way of doing it. SURMA: How do you know your other window? I guess a service worker knows all the windows. But-- JAKE: Ah, that's correct. You don't know the other windows. Because the only way you'll get one of these is if you have-- if you do window.open() or if it's an iframe. So I'm going to have to dock a load of points for that, I'm afraid. This is not a proper method, is it? SURMA: It's an eighth of a method, apparently. JAKE: Yeah, well-- yeah. But also, it has some good parts. Like, you can-- the stuff you can transfer, it could be not just string data, not even just JSON data. It can be binary data, blobs. You can have circular references in your objects. It's a structured cloneable, so it supports all of that. SURMA: Have you-- have you heard of Comlink? JAKE: Yes, and I'm sure Comlink can help here as well. And I should say that this is the only method we're going to look at here that actually works cross-origin. So I'm actually going to give it some points back for that. So it has specific use cases, but like you said, not generally useful. It's good at what it does specifically. But for keeping state across a whole app, it's just 0.248 of a way. I would say I don't have time to go through the very complicated and scientific scoring system that I'm going to be using here. But just trust me that it is-- SURMA: Just trust you that this is absolutely deeply thought out and completely accurate. JAKE: Absolutely. Absolutely. If I did the same test again, the same numbers would come out. I've not just picked these out of my-- how dare you. How very dare you even suggest-- SURMA: You picked them out of your what, Jake? Where did you pick them? JAKE: All right, let's leave that behind. Next one-- this is event source. So this is a persistent server connection. There's other ways of doing this. You could use fetch, fetch streams. Have you heard of them? But that doesn't work in Edge, annoyingly-- well, old Edge, sorry, in the old Edge engine. And there's web sockets as well. SURMA: And you need your server. I mean, come on, this needs a server. JAKE: And this needs a server. So yeah, that's-- SURMA: Don't like it. Don't like it. JAKE: Well, do you know what, you're right. Because if you've got eight tabs open, that's now eight connections you're keeping, and the same data being sent to you eight times. So I'm sorry, going to have to dock some points for that. That's no good, is it? But it does mean you can communicate cross-device, which is pretty good. SURMA: How do you know that events sources are coming from the same client on the server site reliably? JAKE: Well, you-- cookies. So using cookies, you'll have state. You'll know the login. SURMA: Fine. JAKE: Yeah. I mean, sometimes you don't need that. Like, I don't know, I find it really satisfying if I close an issue or merge an issue on GitHub on my phone, and I see it happen on the screen as well. It's like, whoo-hoo, that's good. SURMA: But that's public. OK, I was still thinking in the time zone thing, which is an inherently personal adjustment, while something like an issue, that's, quote, unquote, "global state." So that makes sense. Yeah, OK, I'm with you. JAKE: Yeah. I'm actually going to give it a few points back. Because it's useful for-- you could do some smart cross-device stuff. But yeah, it's very specific. And yeah, it's a shame that we don't really have a way, right now, to sensibly dedupe a connection. So if you find that you've got eight tabs open, you kind of want one to be the main tab and then do a different method of communication to give that information to the other tabs, shared worker is a great way of doing this. But it's not well-supported SURMA: I was waiting if I should-- if I can bring up shared worker or if you have it in here. Because that is the thing that I wanted to use for my actor model stuff as well. But it's so horribly badly supported that it's just not a realistic option. JAKE: I literally just thought of another thing you could use for this. The Web Locks API, you could have one thing set up a connection and create a web lock. And then the other tabs will wait on that web lock to expire before they try and do it. I don't know, there's probably some raised conditions in there. Anyway, I haven't thought about it properly. So I'm going to talk about it anymore for fear of embarrassing myself. Here's another one. This is like, when you change local storage or session storage, all the other windows, they get this event. SURMA: I did not know this. JAKE: I think this is really cool. Because you get the old file, the new file. You even get the URL of the page which made the change. SURMA: Can local storage store objects? JAKE: No, it can't, just text data. So I'm going to dock some points for that reason. But it's fine for small bits of data. You could also use it-- and I've done this before-- use it as a signal just to say this thing's changed, even though the data is actually somewhere else, like IndexedDB db or cache API. I can use just a little-- SURMA: I think this would've been useful for my actor model thing. Because what we ended up doing is using IDB and polling it. JAKE: Ah, oh. SURMA: "Pulling" is the word-- not polling, pulling. JAKE: Yeah, still, oof, that's harsh, yeah. So one reason you might not have used it in your actor model is it only works in a window, not a worker, because local storage, right? SURMA: Yep, that would make it a non-starter. JAKE: Yeah, exactly. So let's dock some more points for that. Although that hasn't been a problem in practice for me where I've used this in the past. This is actually how I did the time zone change. Because it was only ever reflected in a page. SURMA: That makes a lot of sense to me. JAKE: So I used it for that. And it was dead simple. If you're only dealing with dedicated workers, you could have the page here, this event, and then post message the worker, whatever. SURMA: True. JAKE: But my main problem with this is it only alerts other windows to the changes, which is a little bit of a pain. So in this case, I've got another component on my page. And it's listening for this event as well. But if the other component updates a value, my component's not going to hear about it. Because it's only going to tell other windows. SURMA: Oh, it doesn't-- you don't get an event on your own window, OK. JAKE: Exactly. SURMA: Yeah, that's annoying. That is annoying. JAKE: Yes, that's a problem. So yeah, I'm going to dock some more points. It's still really useful. But I'm going to say this is like 0.763 of a method according to my calculations. OK, let's keep going. Broadcast channel-- SURMA: Ah, love it-- JAKE: Love it. SURMA: --if it was real. JAKE: Yes. It is real. This is real. You use this today. SURMA: Barely. JAKE: But one of the nice things about this is it's structured cloning, which is great. It works in workers, which is great-- so all different kinds of objects and whatever. But also, it will message other channels on the same page. It will message itself, but it will message any other channels of the same name. So you don't have that problem that I showed before. It just works around that, which is really nice. But-- and I think you were slightly alluding to this-- it's not symbolic in Safari, is it? SURMA: It's not. JAKE: And that's the only modern browser that doesn't support it. Chrome was late to the party with this. It was in Firefox for a while before it reached Chrome. SURMA: True. JAKE: But we've had it for a few years now. And this is top of my list of things I really want in Safari. Because it's just-- yeah, anyway. I'm not over it, but we'll move past it for now. Service worker-- so this listens for events that are sent by the service worker to other clients. So this works in workers. It's structured cloning again. A little bit more complicated, because you have to do things manually when it comes to sending. SURMA: Yeah, the service worker side is a bit convoluted as well. JAKE: Yeah, so here I'm post messaging to the service worker to say, hey, please broadcast this for me. And then the service worker is going to pick up that event and then broadcast it back. This is useful in the multi-component case as well, because you get to decide whether it posts back to the same client. And I tend to. I always post back to the main client. In fact, I use that as my source of truth. Like, one component will send the data to the service worker. But then it won't apply that data change until it hears back about it. And that works in a multi-component web components case. But you know, that's preference. You get to do-- get to do whatever you want. So that's one way of doing it. And I'm actually going to leave that at 1. Because that's my favorite method when I need all of those features. SURMA: And the post message-- sending something to the service worker will wake it up in case it's been killed. And it will have, always, a correct and complete list of all the clients, right? JAKE: Yes. Yep, when you call match clients, that's when it will go and get all of those. By default, it's only controlled clients. But there's an option to say, give me the uncontrolled ones as well. By default, it's only pages. But there's another option where you say, I want the workers as well. So yeah, that's all in your control and up to you. One last one-- here we go. Oh, ho, ho, ho, ho, look at this. This is-- SURMA: Are they finally a thing? JAKE: --an IDB observer. SURMA: Yes. JAKE: So you create a callback. And then you say what you want to observe. Works in workers. You get a complex type, because it's all of the IDB stuff. It has everything. So you can just use your IndexedDB as the central store for your state. And then your components can listen for when the bit they care about actually changes. So it is a way for-- SURMA: And it's not supported. JAKE: It's just an-- it's just an explainer. I think there's a partial experimental implementation in Chrome. And worse, this explainer hasn't been touched in 2017-- SURMA: Oh-- JAKE: --which is a lot of years in web years. SURMA: You got me hopeful there for a second, right? JAKE: I know. SURMA: Because I knew they were working on it. And I was like, is it happening? Are they a thing? JAKE: I just wanted to play with your emotions a bit there. But [INAUDIBLE],, we both really want this, right? SURMA: Yes. JAKE: This is what-- this is how we want to build apps. We want to be able to store all of the data in IndexedDB and then use observers to-- so one component's like, I only care about this bit. I only care when this thing changes. So just let me know. SURMA: Yeah, imagine if you could put your redux state into IDB and have all the other components just subscribe to it via IDE observer. And if the page reloads, it doesn't matter. All the state is still there. It's like, it would be so many things I wanted to try if they are actually feasible. JAKE: Actually, I would love to also have a session IndexedDB store as well-- SURMA: Yeah. JAKE: --so a way that you would say, I want this, but just for this tab. And if this tab closes, [INAUDIBLE] data. And that also means-- ah, it depends. Again, depends who you ask whether this is the spec behavior or not. Session storage, in some cases, survives a tab crash. So tab crashes-- reload, and you've only lost whatever happened before your last commit to IDB, which is great as well, right? SURMA: Yes. JAKE: I know I'm not-- I'm ending on a sad, sad story. SURMA: On a 0.005. JAKE: That's all I've got. Hopefully, one day, we get this. But in the meantime, yeah, I think the service worker way-- SURMA: Now in thinking, do your numbers actually add up to 3.145? JAKE: I hope so. SURMA: 3.143. JAKE: I hope so. Because I sort of panic added it up at the end. But it is entirely possible I missed-- SURMA: But you did at least add them up. If it was me, I probably would have just written math.random on every slide. JAKE: I definitely attempted to add them up. Whether I got it right I'm not, I'm-- do you know what, I reckon we'll hear about that in the comments. SURMA: Oh yeah, we will. And you will get told off if it's not correct. JAKE: It's all I deserve. [MUSIC PLAYING] Just one second, because I'm really worried. Because I thought my fan went off during that episode. So I just want to double check that everything actually recorded. I don't have any error messages. And I have 17 minutes of recording. Yeah, yeah, yeah, yeah, it's all recorded. Thank Christ for that.
Info
Channel: Google Chrome Developers
Views: 17,760
Rating: 4.952064 out of 5
Keywords: GDS: Yes, Synchronising across Pages, ways to synchronise data between documents, sharing data between documents, synchronise data between documents, comlink library, service worker clients API, IDB observers, json, synchronization, events, local storage, new videos from Chrome, Chrome, Chrome Developers, Web, Chrome devs, developers, Google, tech, tech videos, web, videos for developers, Jake and Surma
Id: 9UNwHmagedE
Channel Id: undefined
Length: 16min 20sec (980 seconds)
Published: Tue Sep 15 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.