291

October 14th, 2020 × #web-app-updates#app-versioning#refresh-strategies

Hasty Treat - Updating / Restarting Long-Running Web Apps

Strategies for updating web apps and forcing users to get new versions, including manual refreshes, service workers, hot reloading, and visual notifications.

or
Topic 0 00:27

Updating web apps running persistent data

Scott Tolinski

Welcome to Syntax. In this Monday, hasty treat, we're gonna be talking about updating applications or web apps that have been running for any bit of time. This is definitely a concern that many people are having as we move more and more into the world of web applications that have persistent data and all sorts of neat things that you might expect a modern web app to have.

Scott Tolinski

Now this episode is sponsored by a service that you're going to have to have if you have any of these TypeScript applications, and I'm talking about LogRocket at logrocket.comforward/ syntax.

Scott Tolinski

What is LogRocket? Well, LogRocket is the service that allows you to see your bugs happen as they happen, as in a user goes on your side to click a thing and the thing breaks, and then you might be left to try to figure it out or piece together what happened through error logs, which is, as we know, not that much fun. What LogRocket does is it gives you a scrubbable video replay of the user actually clicking the thing along with the network tab, the console, or any of those things that you're typically used to when solving the bugs in your local environment.

Scott Tolinski

It's very, very cool and something that you're going to need to see to believe. So head on over to logrocket.comforward/syntax and get 14 days for free. I gotta introduce my cohost. Who am I? As always. Oh, well, my name is Scott Zelensky. Okay. Let's just get that out of the way first. Now with me, as always, is the Wes Bos. Hey, everybody.

Wes Bos

Hey, Wes.

Wes Bos

Alright. So this is a sign that just popped up the other day for me. I don't have anything like this in place, and I'll tell you, like, what happened to make me start talking about this JS I rolled out a new version of my course player, and it fixed some bugs. Like, I was in my, my Sentry, and I had a a couple bugs in there. I fixed them all and marked them as resolved.

Wes Bos

And then I started getting emails about the same bugs coming back, And I was like, that's weird. I just fixed these. I was like, oh, it's because people are still on the old version of the app because, like, they're they're sitting there. They're watching their course. They're not gonna refresh the page. They'll pause it, come back to it in 3 days, and and keep going. So they're running the code, and, luckily, it wasn't like a a breaking error. It Wes just a a little warning that kept popping up. And I was like, oh, like, well, I guess I gotta wait for all these people to refresh the page so that they can get the new version of of the the course viewer.

Topic 1 02:17

Users on old app version get bugs fixed in new version

Wes Bos

But until then, I just kinda have to sit on my hands and know that these things will roll in for probably a couple of weeks because people I don't know. Some people are tab monsters and and keep those tabs open forever.

Wes Bos

So I started I went on Twitter. I was like, like, what do you do when you release a new version of this app and you want people to to get that new code and stop running the old code? So I don't have anything for this. I thought I'd ask you, Scott. Like, do you do anything of this before we go into the solution?

Topic 2 03:22

Meteor hot reloads new versions to users automatically

Scott Tolinski

I do. In fact, let me tell you what I do for this. I use platform that has it baked in, which is Meteor.

Scott Tolinski

Meteor, basically, when you do a new deploy, if you're using all of Meteor's own data stuff and you're using Meteor, it just pushes everything live. In fact, it's ESLint interesting. If I were to make a Node change, people in the past have been, like, using the site, and they'll be like, hey. The background changed. It just pushes it. It just pushes it via WebSocket. Just, like, hot reloads it? Hot reloads it. It's amazing. Right into the user's thing, and it's done it since day 1. And people don't talk about it, but it's it's fantastic. No kidding. That's amazing. Wow. So this is not a problem Scott has ever had Nope. Because he's been he's had this, like, next level thing for many years. Although you could consider it to be a problem if the user's code is just changing in front of them. But if it's, like, minor things or whatever just popping in here or there, like, that's I think that's that's fine. You probably wouldn't want some, like, substantial update to, like, come in and, with you know, and also, like, if you have platforms, like, you think about, like, Notion. Notion is a a platform that we use for note taking and planning it with, like, a database. Yeah. Like, whenever they have a pop up to tell you to reload the app, it actually, it gives them an opportunity to introduce new features, which I I find to be really neat because they're always, like, oh, click to refresh, but also here's what's new. So that way you're actually inclined to refresh. Where for me, I I wouldn't I don't know what the solution would that be for me, but that wouldn't be something that would be super easy for me to accomplish. Can we at least appreciate that releasing a new application on the web is refreshing and not downloading, updating, rebooting your computer? Like, how good do we have it as as developers that the problem we are facing right now is how do you get the user to refresh the page? Right. I know. I know. It's it's it's funny that we we say that because it's like, what was it? We were we we had, like, an issue with Safari not supporting something in Clamp or something, and, like, a Safari dev was like, update your computer. And, like Yeah. Oh, so I have to update my computer? Like

Wes Bos

Yeah. Yeah. So it it's it's a good life. So what we're gonna do now is just go through some of the solutions that people I asked on Twitter. What are the solutions that you have? So the 1st solution which I have taken is do nothing and hope the user refreshes.

Topic 3 05:36

Do nothing and hope users refresh

Wes Bos

Second 1 we have here, and and this seems to be a lot of what people do, is they have a list of assets or, like, commit hashes. So every time that you build a version of your website, you'll often get, like, a hash. This is pretty popular in, like, a webpack build or something like that. You can pull the server because you could have, like, an assets Scott JSON file, and you could just pull the server periodically or have a WebSocket that would push, hey. New version available, and your your code will know when there's a new version available. And you could do a couple things. Probably the easiest is just throw up a toaster. A toaster is, like, a bottom right hand corner, a little pop up that says new version available, refresh to update. I think they're just called Toast.

Topic 4 06:17

Show "new version" toast notification

Wes Bos

Toast Toast. Message? Toast messages? Yeah. The toaster would be the thing that pushes the message up. The toast would be the actual message itself. Right? I have never heard of the word toaster being used in this, but that sounds, like, pretty sweet, though. Like, it pushes it up. I I like that. If that is real, then, I always imagine that if I were to monkey with the CSS, there would be a toaster

Scott Tolinski

just below where those messages come up. Well, I guess you're right. I'm seeing I'm seeing the thing in Dojo.

Scott Tolinski

Remember Dojo? Dojo calls there JS a toaster. Okay.

Wes Bos

So you could prompt the user to refresh. You could just manually refresh the user. So that's probably not the best idea, but you could if especially if you're using some sort of state management library. If the user is partway through some sort of, action where they've typed some some data in the Bos, Yeah. Watching a video. You save all that state to local storage, refresh the page, and then try to apply that state back into your thing, so it'll just put them back to where they are. That would probably be a good idea Wes to count and wait for some period of inactivity.

Topic 5 07:21

Refresh after period of user inactivity

Wes Bos

So, like, if the user hasn't done anything in 10 minutes, they're probably not on that tab, or or you could even listen for the focus state of the window knowing that the user JS no longer on that. And and then once the focus state is lost,

Scott Tolinski

start a timer and wait for, like, a minute or something like that, and then and then go ahead and and refresh the user. I would say that that's probably not a great solution for people who are on a video site or have a video site because if you're refreshing in the middle of a video, like, that would that would make some people upset. I know I would be upset if I was watching a video and all of a sudden I stopped talking and, it refreshed.

Wes Bos

Yeah. Yeah. You'd probably have to make sure that No media playing. Like, in a playing state or something. But, anyways, it's probably not a good idea because the next one, which a couple of people said, and this is genius, is so all of your links on your application, if you're using a a React or Vue or or Angular, your links are are probably push state, meaning that you click on a link, it changes the URL bar, and it it loads in the new video or whatever. But you're not actually doing a full page reload. That's just happening in the browser.

Normal links force refresh, router links don't

Wes Bos

And a few people said, Node a custom link component that checks if there's an update.

Wes Bos

And if there is an update, just make it a regular ESLint, and just have the page do a full reload, and, otherwise, return the regular React Router or Next. Js link. And I thought that was genius because, like, what a way to update a website JS just turn your links into regular links. How do you pull that off, though, technically? Like, you would make a new component that imports like, let's use React Router. It imports link from React Router. And then inside of that component, you could have something that periodically will pull the back end for a new version or or maybe even just run a timer that says, like, when has this application last been reloaded? If it's more than 24 hours or something like that, then you can dynamically either render out a rack router link or render out just a anchor link.

Wes Bos

They render out to the same thing at the end of the day. Just one of them has pushed it, and one of them doesn't. And because it's it's all dynamic, it it would just render. You can change out a React router link to a regular anchor link, and the user will have no no idea that that happened because there would be nothing that visually changes.

Wes Bos

Neat. That's pretty ESLint. Yeah. Yeah. Yeah. I thought that one was there was somebody like that posted that. I haven't they're like, I haven't tried this, but this is what I'm thinking. And everyone's like, oh my gosh. That's genius. Like Yeah. Just click a link it open. Yeah. Yeah. Because, like, the user will continue to interact with your application, and the next interaction they have that changes the URL, which is a lot of interactions, will load the new app for you. Neat. Very neat. Next 1 is just use a service worker. So service workers have this built in. The way that a service worker works is that you register your scripts dotjs, And then the next time somebody comes to that website, it will it'll say, oh, I have a cached version of Scripts JS. So Node that Scripts JS in. But part of what the service worker will do is while it loads up the cache version, it will also check-in the background if there's a new version of that scripts.js available to you. And then there will be an there's an event that's fired when there's a new version of that that scripts available to you. That's a perfect use case. You don't have to write any custom code because service workers already do the checking and alerting that happens. And then you just have to do one of the things that we talked about earlier, swap out a regular anchor link, provide a toaster, do a hard refresh, whatever it is you choose to do for your app.

Topic 7 11:00

Hot reloading updates in development and production

Wes Bos

What else? It's just hot reloading baked in. So I I jokingly said just run development in production, and, hot reloading will work, but I didn't even realize that Meteor has that already.

Wes Bos

And, it looks like ViewPress also has that where it will it'll do a hot reload of your application right in front of the user. And that won't work for every use case, but I would wager to say that will work in a lot of cases.

Scott Tolinski

Yeah. And the cool news about the the Meteor version of it, if you're using Meteor's own pub subsystem, is it sends data along the way. And that works like that that's one of my favorite things about subscriptions. When you're pushing new code in and make changes to the database, man, you get you get basically that free user refresh

Topic 8 11:46

Chrome changes icon color to show update is available

Wes Bos

with nothing with absolutely no skill involved, really. That's pretty sweet. Then, finally, someone said, I know it's not an app, but I like how Chrome handles it with an ever present icon that gets more ominously cover colored the further you are behind.

Wes Bos

Yeah. It does. Yeah. It does. Yeah. At a certain point, people will start ignoring them. I do that on OSX all the time. Pnpm off It's currently yellow. To reboot. Yeah. It just turns a different color at a certain point. The user will have to to refresh the page to get the new version of your app. Sick. Yeah. That that was cool. I'm I'm happy I sort of dove down that hole because I learned a a whole lot about how to do something like that. Hopefully, you learned a thing or two as well. If you have your own thing that we didn't cover today, make sure you tweet us at syntax f m, and, we'll retweet your solutions as well. Alright. That's it. It. Thanks for tuning in. Catch you on Wednesday.

Wes Bos

Peace. Peace.

Scott Tolinski

Head on over to syntax.fm for a full archive of all of our shows, and don't forget to subscribe in your podcast player or drop a review if you like this show.

Share

Play / pause the audio
Minimize / expand the player
Mute / unmute the audio
Seek backward 30 seconds
Seek forward 30 seconds
Increase playback rate
Decrease playback rate
Show / hide this window