 Well, aren't we just finishing up the site? That's pretty much where I'm at, I think, sort of. OK, let me list what's at least to do. There's basically putting in the final sessions, and I'm still waiting on those. There's push messaging and notifications if I can get to it in time. And I think there might be one other thing that's escaping me at this exact moment. If it's important, I'll remember it. If not, I won't have it to-do list somewhere. It'll probably be on there. But since I last recorded a video, it's been a few days. And the reason it's been a few days is because I have been working on the service worker part, and I wanted to try and get that just right. And it's working. I mean, I've had a service worker in place from the start, but I don't know if you remember, but it basically was like a pass-through service worker. It didn't do anything particular. All requests just went through it, and it was a fetch to go and get the resources. And the next step for me was to actually have a populated cache of items and actually respond from the cache and do a couple of other bits and pieces. So let's actually have a look at the code because I think that will illuminate things. Firstly, that will go into the Python because I have got to the point now where we basically hotswap the home page. Oh, actually, well, hotswapping the home page is related to this item. I now have a JSON file of the actual sessions, which is currently filled out with nonsense sessions that I have just made up for now. And you can see that the date is the first key and then the time of each, and this is in PST because that's the time zone of Chrome Dev Summit. It's in San Francisco, which will be PST, which means it's, I think, seven hours behind UTC or GMT as you might call it, depending on how you refer to time zones. I mean, who doesn't just sit there referring to time zones? I know I do. So I've got the JSON file. And the JSON file is loaded in by the Python. And that's actually important because I do things like I basically start to kind of step through. And basically, the sessions file is now the source of all sorts of bits and pieces in the site. For example, I've moved the filters out as well, out to their own file. So we've got things like getting the current session. And so we get the current UTC time and we step through all the individual sessions from that JSON file. I have to add seven hours on, which is that there. This is a bit of a funny way to do date parsing. Normally, you'd pass it things. But because I need to adjust the time, I might go back to this now that I've actually got it working and just tidied up because I could ask to parse it based on, I could make a string and then ask it to parse it properly rather than doing it this way. It's a bit of a funny way to do it. But we have things for getting the current session, getting the next session. And there are some interesting bits and pieces in there. Like, you have to make sure that the next session has a different day to the current day and bits and pieces like that. But it's all dynamic. And also, when it comes to the actual homepage, which is this, if template's non, as in the homepage, we have to make a decision based on the time as the server thinks it is. But that's OK because all these things are in UTC anyway. Mostly, basically, if the number of days between the first day of the conference and today is zero, adjusting for PST, then it's the live day one. If it's the second day, live day two, because these will, I think, have different YouTube embeds. So I have to have different, effectively, different files for those different templates. And then the final one is we're not on neither day of the conference, so show the homepage. This works just fine. In fact, let me just show you what happens. I will do this without any service worker. So we'll just directly, if you hit command shift R, if you're working on service worker stuff, command shift R will actually cause your page to load. You can see it in the network stack. Cause it to load without any service worker. And none of those requests are going through the service worker. So that can be a really good way to sort of test that is my server actually responding with the right things before I introduce the service worker. Let me also, while we're here, let me just change the date and time. So I've set it to yesterday, if you like. So let's set it to the first day of the conference and then hit command shift R. And you can see that it's not only is it, let me just move this out of the way. I'll do that. Actually, we'll come back to that in a little bit. So you can see that I've actually chosen the developer diary day one. So I know this is actually the day one. It's just like, oh, OK, it's definitely doing the right template. It's day one. And you'll see that up next, and this has been adjusted for local time. If I disable JavaScript for a moment. La, la, la, la, la, la, down here, up here. Disable JavaScript, there you are. Command shift R. You can see it's 8AM PST, or it doesn't have the title in there. Oh, I'm going to have to go back and fix that. And if we re-enable JavaScript, it's the same content once I've got the title back in there. But it's been adjusted for the local time, which is just done in the JavaScript. I have a bit of JavaScript that constantly, or not constantly, but kind of watches for changes in the schedule, which I can show you. If this video doesn't get too long. Anyway, the theory then is this is day one. And you can see that coming up at 4 o'clock local time for me, which is in about, what, five hours? There are thereabouts. Five hours, it'll be registration and breakfast. Obviously, as we get into the other sessions, it'll make more sense open date and time. So let's say it is, in fact, 6 o'clock in the UK. You can see now we've got the current session is Alex Russell. And oh, good, we've gone from breakfast pretty much straight to lunch. This time traveling thing is working out just fine. So anyway, as you can see here, I've got this refreshing listing in just less than a minute. We could wait, see what happens next. I might get them to time-lapse this. Still waiting. There it goes. Well, it happened. You can see that the one that was up next becomes live. And now the next one has appeared in the listing. So that will be, as the video is playing, I'll basically be swapping the session. So that's kind of what happens with the live stuff, which is all very, very cool. And the code for that is kicking around in components. There's a live session info, which basically goes through. It's sort of, in many ways, it's a duplicate of those filters on the server side, because it's got to do similar kinds of things. It's got to look through that session, Jason. So they share that, Jason, the server side and the client side, both look at that same, Jason, and make some decisions on what the next session switch time will be, which is basically look for the next session and find out what the time is and then set a timeout to basically go and do a check for that, which is, it works just fine. Well, it seems to work just fine anyway. So that is all working. If you JavaScript, it's swap sessions, all that. Now, if we reload and look at the network, these, all these requests are actually coming from the service worker. Let me show you the service worker. The service worker from the top, import scripts. And then I'm sure you recall the ad hash remark filter thing. That basically is going to make sure that if this file changes, that this import scripts line is going to actually be different. So if we look at the service worker itself, you can see that it's cached up manifest and then there's the long alphanumeric hash string that goes in there. If I change whatever the contents are of this cached manifest, then this will get updated. The service worker will update. It'll run its install and its activation and go through its lifecycle. If, by the way, you have not come across the service worker lifecycle, there is a brand new document guide article thing on Google Web Fundamentals, which we will link to in the description and possibly they'll even put one of those fancy annotations on this video as well. Who knows? So what goes into the cached manifest glad you asked. The cached manifest is here and you'll see that it's basically a list of all the things that I want caching and good news, I don't create those myself. Or this myself. What I do is I go to, I've made this file called build resource list and I have a bunch of things that I want it to ignore and I have a bunch of resources that like URLs that I know I definitely want like the various sections of the site. This partial flag means that I actually don't have the server bake in any of the session information. It just means that those, they come through empty because I know the JavaScript is gonna populate them later on. I also get the session information and I go through each session and I get its URL because I know I want to cache that offline. And then I walk through the static file. So I go through dot slash static. So basically the static file here which has the images, the JSON, the JavaScripts excluding the service worker itself, the styles and any third party stuff and manifest and whatever else. That, as I say, results in this big long file here. And in the service worker once that gets imported and whatever else, the install essentially steps through each of those and it makes a request for each of those and it will wait until the caches have been opened and we've added all those items and then it does the skip waiting which basically means go straight to the activated stage. So the lifecycle is sort of, it's installing and then it waits until all the clients that are connected to the service worker have disconnected as in you do like a force refresh or you close the tab. When all the tabs to the Chrome Dev Summit site have closed, it would normally then switch the service worker across to activating. But in this case, I'm telling it to just go straight to the activating stage. Don't worry about anything that's already connected. I'm hoping that will work out fine. I'm hoping there won't be any breaking changes by doing that. The activation itself looks through previous installation caches. So every time we install the service worker that populates the cache, I'm saying find all those other caches that aren't this one, the one that we've just populated through the install and get rid of them, delete those caches so that we're not building up space and spaces and space over time. This probably could do with a little bit of improvement in that I think it should possibly have a couple of caches, caches for things that are less likely to change and caches for things that are more likely to change like the JavaScript or the CSS. I'm likely to find minor things in there, minor bugs that I just want to tweak or change or whatever. And so rather than invalidating the whole cache and downloading everything every time, a better version of this would be the things that I think are likely to change. Those should have their own cache that I can just delete and repopulate. And the things that I think are pretty static and unlikely to change, put them in their own cache as well. Again, it's a function of time to see how, you know, how we get on. And this client's claim, if I understand it correctly, on activation when this service has been activated, it basically says, okay, I will now respond to all future requests from this point on. So if the page then asks for an image or a URL, I will handle it. And it basically pushes the old service worker off to wherever service workers go when they're not needed anymore. Oh, on message, this is an interesting little thing. I mean, I think it's an interesting little thing. I wanted to do this. I was like, how do I decide whether to notify somebody? Like if the service worker changes, it might be a minor change. And I don't really wanna kind of put a little thing that's like, hey, new version. Cause it might just be really minor. It just might be like a typo or something. And I'm like, yeah, it can cope for next time. What I do is the version that's baked in here, which is from the package.json. If it gets a message asking for version, and that message will come from the page, and I'll show you that code in a moment. It basically posts a message back saying, here's my version. In the service worker install, the, where are you? Where are you? Yeah, if we've got an active service worker, we post message going, what's the version? When that comes back, if we've not already kind of had a version, then we store that. And then if there's one that's updating, as in we get, so you've imagined the situation, you've got one service worker, it's installed, it's running, it's activated, it's doing its thing. And then a new one comes in. And it's like, okay, I'm taking over. Well, we've asked the first one, what's your version? And it said 0.1, 0.0, cause it's semva. Let me just do that. Let's say 1.0.0, that would have been a better one. And so we've got that version back. And then the new one gets installed and we ask it, what's your version? And it comes back and says, I'm 2.0.0. I've basically said, I split the current and the new version on dots. And I basically said, if the major version is the same, just log it out to the console going, yeah, I updated the service worker. If it's a major version change, like 1.0 to 2.0, then we push this toast that's like, really, you should refresh the site. And again, these are things that I might just improve over the coming days. We'll see how we go. So you can see, actually, if I go to package.json and I change that to 2.0.3, hopefully, when I refresh the page, that I see site updated, refresh to get the latest. Whereas, if I do 2.3, 2.0.4, what I look in the console, you can see we just get this service worker move from 2.0.3 to 2.0.4. So it's a way for me to kind of decide how much do I want to bother the person at the other end. Okay, I don't want to take up too much more of your time, but I do think it is worth looking very finally at the fetch itself. This is the function that's gonna be called whenever you make a request to the page. One thing is, if the image ends in at 1x, I always respond with a 1.5x. This means that I can, I only have to cache the 1.5x and I will just hot swap it. It doesn't matter. You've asked for the 1x, you get the 1.5x. In my case, it's always background size cover, so I can respond with a bigger image. And it means I don't have to cache the 1x and the 1.5x offline. It's handy. If the request itself doesn't end with dev submit, then I just say stick to the current request. But if, however, you have asked for the homepage, I go through the sessions and I basically look at each day and I adjust for PST and then I say if you're inside the first day, respond with Live Day One from the cache. If you're inside day two, respond with Live Day Two from the cache. And if not, you're gonna respond with the dev submit slash home. And then if there are any errors, just respond with dev submit slash home. So that means that what we get is, we basically call this first. So we were saying, either we're just gonna leave the request as it is or if it's a request for the homepage, we might remap it just like the server was doing in the Python. We have to replicate that behavior in the service work. And I guess if you had a JavaScript server, you might actually use the isomorphic. I mean, as bad as Jake, he couldn't say isomorphic either. Isomorphic JavaScript, there we go, to do the same logic here of kind of going, is this on the conference day one, day two, if not respond with whichever page, whatever. So we're doing the same kind of remapping and rewriting. And if we didn't do that, then on the conference days, you might get the old homepage and you'd have to kind of force refresh to see the live stream, which we don't want. So we potentially remap the request if it's needed. If not, we'll just leave it as is. Check for the cache. If the cache has got that request, which for all of the files apart from, say, like YouTube thumbnails, anything for analytics or basically any third party stuff, it won't exist in the cache and we'll just fetch it. And for everything that we do have from the cache, we'll just respond if we've got it. So goodness me, that was a lot of information, wasn't it? But it's been a few days since I've had chance to record a video. So there you go, that's what happens if I don't record them often. At this point, I think the site is pretty much shippable and this will probably be the last dev diary that I'm gonna record. And maybe if there's something that comes up in the next little while, that's like, oh, I must tell you, then I'll be back. But for now, all I wanna say is thank you so much for coming on this journey with me. Thank you for all the comments, all the feedback, all the chatter. And I hope you've enjoyed coming along this journey with me, I've enjoyed having you along and you know what, let's do this again sometime. But maybe you can do the coding. Yes, what a concept. Tiddlyoo!