Mastering Browser Caching with Vitali Zaidman - JSJ 490
The Jabber panel along with Vitali Zaidman jump in and discuss how your browser cache works, what the standard is, and what you can expect when you're trying to take advantage of the performance characteristics of your users' browsers. The browser cache control settings and techniques are not straightforward, so buckle up and learn how to get your browsers to load assets from memory.
Special Guests:
Vitali Zaidman
Show Notes
The Jabber panel along with Vitali Zaidman jump in and discuss how your browser cache works, what the standard is, and what you can expect when you're trying to take advantage of the performance characteristics of your users' browsers.
The browser cache control settings and techniques are not straightforward, so buckle up and learn how to get your browsers to load assets from memory.
Panel
- AJ O'Neal
- Charles Max Wood
- Dan Shappir
- Steve Edwards
Guest
- Vitali Zaidman
Sponsors
Links
- Intro To Service Workers & Caching - YouTube
- Love your cache: Optimize for the second load - YouTube
- HTTP caching
- Two Important Differences between Firefox and IE Caching
- Vitali Zaidman | Software Architect | Personal Website
- GitHub: Vitali Zaidman ( vzaidman )
- Twitter: Vitali Zaidman ( @vzaidman )
Picks
- AJ- WASM, Rust, the State of Async/Await - Utah Rust Nov 2020 - YouTube (CloudFlare Workers w/ WASM + Rust)
- AJ- Beyond Code Live 004 - How Domains (URLs) Work - YouTube
- AJ- Beyond Code Live 005 - Setup your First Server, Right Now (and get $100 or 60 days free) - YouTube
- Charles- Fanatical Prospecting
- Charles- Riverside.fm
- Steve- Why Don’t Sheep Shrink In The Rain?
- Steve- The wholly pun_bible | Instagram
Contact AJ:
- AJ ONeal
- CoolAJ86 on GIT
- Beyond Code Bootcamp
- Beyond Code Bootcamp | GitHub
- Follow Beyond Code Bootcamp | Facebook
- Twitter: Beyond Code Bootcamp ( @_beyondcode )
Contact Charles:
Contact Dan:
Contact Steve:
Special Guest: Vitali Zaidman .
Sponsored By:
Transcript
CHARLES MAX_WOOD: Hey everybody and welcome back to another episode of JavaScript Jabber. This week on our panel, we have AJ O'Neill.
AJ_ONEAL: Yo, yo, yo. Coming at you live from absolutely perfect paradise, Virginia, aside from the bad internet,
CHARLES MAX_WOOD: Dan Shapir
DAN_SHAPPIR: coming to you from, well, interesting Israel,
CHARLES MAX_WOOD: Steve Edwards.
STEVE_EDWARDS: Howdy from sunny and clear Portland.
CHARLES MAX_WOOD: I'm Charles Max Wood from devchat.tv. Just a quick shout out. We do have now a premium podcast offering. Currently it is ad free episodes. We are looking at what other options we can add to it to make it more exciting, but you can go find it at devchat.tv slash premium. And this week we have a special guest on the show and that is Vitaly Zaidman. Vitaly, do you wanna just say hello to everybody? Remind everyone who you are and what you do.
VITALI_ZAIDMAN: Yes, hello from Tel Aviv. I've been a software developer for the last nine years. I work in the software solutions company in Weldon software. Great company by the way. And I got to work on many projects, many technologies. I worked with a lot of teams, processes. So I know things about tech, mostly about the web. And now I'm leaving my job and I'm moving to London and I'm looking for a job in London, so you know how to find me guys.
CHARLES MAX_WOOD: You and Dan won't be neighbors anymore.
VITALI_ZAIDMAN: Yeah, that's true.
CHARLES MAX_WOOD: Yeah, but the barbecues, it's going to be sad.
DAN_SHAPPIR: Yeah, but we live in this global sort of a world of an economy, right? I mean, with Twitter and Facebook and whatnot, you have friends all over the place, so sort of these internet friends.
CHARLES MAX_WOOD: Yeah, absolutely. But the virtual barbecues just aren't the same. So yeah, so let's just dive right in here. I mean, maybe you can browser cache your barbecue. I don't know. The title is Browser Caching. That was a joke worthy of Steve Edwards.
STEVE_EDWARDS: No, mine get laughs. Well, they should at least. I don't know about that one.
CHARLES MAX_WOOD: But yeah, so, and this is something that I always run into. It's like, okay, it's like, okay, I'm gonna add some characters on to bust the cash, make it reload stuff. But yeah, it's not something that I really think about other than, oh, my framework does this for me, right?
This episode is sponsored by Sentry. Sentry is the thing that I put into all of my apps. First, I figure out how to deploy them. I get them up on the web, then I run Sentry on them. And the reason why is because I need to know what's going on in my app all the time. Yeah, I'm kind of a control freak. What can I say? The other reason is, is that sometimes I miss stuff or I run things in development, you know, works on my machine. Well, I've been there, right? And then it gets up in the cloud or up on a server and stuff happens and stuff breaks, right? I didn't configure it right. I'm an idiot and I didn't put the AWS credential in. I didn't do that last week, right? That wasn't me. Anyway, I need that error reported back. Hey Chuck, I can't connect to AWS. The other thing is, is that this is something give me information on and that's, hey, it's too slow. It's not performing right. And I need to know it's slowing down because I don't want them going off to Twitter when they're supposed to be using my app. And so they need to tell me it's not fast enough and Sentry does that, right? It puts Sentry in, it gives me all the performance data and I can go, hey, that takes three seconds to load. That's way too long. And I can go in and I can fix those issues and then I'm not losing users to Twitter. So if you have an app that's running slow, if you have an app that's having errors, or if you just have an app that you're getting started with and you wanna make sure that it's running properly all the time, then go check it out. They support all major languages and frameworks. They recently added support for Next.js, which is cool. You can go sign up at sentry.io slash sign up. That's easy to remember, right? If you use the promo code JSJABBER, you can get three free months on their base team plan.
DAN_SHAPPIR: Before we dive into it, in preparation for our conversation today, I went ahead and started reading the MDN chapter on the cash control HTTP response header setting, because MDN is the best. And I have to quote a part of it back to you because I think it kind of frames this entire discussion. So one of the directives there is the no-cash directive. And here is the description of no cash. The response may be stored by any cash, even if the response is normally non-cashable. In other words, no cash means that it can be cashed. You've got to love that.
CHARLES MAX_WOOD: Logical.
STEVE_EDWARDS: Hey, real quick. There's one thing at the top of the notes that I think is important leading in, but the famous statement from Phil Carlton that says there's two hard things in computer science, cache and validation and naming things. Actually, that's incorrect. There's two hard things, computer and computer science, cache and validation, naming things, and off by one errors. So I just wanted to clarify that.
DAN_SHAPPIR: Yeah, that is well known. But yes, cache and validation is certainly hard, especially hard in a distributed and not, let's call it not reliable system like the web, intentionally not reliable. So it makes the caching even more challenging. But that said, I am amused by the fact that caching on the web, the various values that you can put in the cache control header are very, let's call it, not intuitive, to say the least. And I guess that that's what we're going to talk about today, no?
VITALI_ZAIDMAN: Yeah, I guess that's, yeah, actually, exactly. So I was amused by how things were cached on my website, on the website that I work a few years ago for the first time and I researched it then, but I forgot that I researched it then by now because it's so not intuitive. So every time I work on it, I have to read the documentation from start to end. I always read it when I start working with it because there's so many variables, so many things that you need to remember. Yeah. So what I saw basically was that I had images and these images were seemingly the same. And I started like doing all this like trying to understand why they are cached differently. And it was consistent. Some images were served from the browser, from the memory, which means that to get, I don't know, dog.jpg. You don't even have to go to the network. That's the fastest scenario. Obviously you just get it from the browser. And the browser cache, some images were served using the three or four a header, which means that the browser makes a request. The server basically says that, yeah, it's cached and some requests were giving me like other codes, like 200. And it was and I couldn't find what's the difference between them. So I'm going to talk in a moment. What was exactly the difference and how it works.
STEVE_EDWARDS: So before we get going too far, Vitaliy, I always like to go back and address some basic stuff, because a lot of times we get into talking about complex things without explaining why it's important or what it is in the first place. So for someone who's listening who might not understand cash and here's the way I'll explain it. So my first dealings with caching came with working in PHP based sites, Drupal websites, et cetera. And the idea is that you have your PHP code, your server code that goes and queries the database to get data to display, turn around and send to your templating system or however it is that you are displaying your data. And if it's the same data over and over that people are requesting, you don't want to have to make the request down to the database, get the data and return it. So instead you cache, you store it already rendered or however you want to do it. In something like reverse proxy server like Varnish, I know it was a real popular one. So that it's real quick to get the data, it's already there, you return it, you have a faster response time instead of making that whole run down to the database. And so the idea of caching is just to speed things up, to save things that don't need to be completely re-rendered on every call. And then it just makes your site much more responsive. You know, going back, I can remember when Facebook first started for instance, and they were using PHP and MySQL. And one of the first tools I can recall them coming up with to help with this was called BigPipe and it was basically a PHP caching mechanism that could be used and it was incorporated into Drupal. And I don't know about how many other places. So that it was an easy way for you to get your data stashed somewhere. So that's easily, easily accessible without making that full run. And some cases you can do stuff like store already rendered data in your database and cache tables. And then there's stuff like Redis you can use, reverse proxies like Varnish, there's any number of tools. But anyway, I just wanted to get out there the whole explanation of caching, what it is and why it's important. And so then as we go and talk about details, we know why we're doing all this in the first place.
DAN_SHAPPIR: Yeah, it's great that you mentioned these points because it's indeed really important. At the end of the day, like you said, Caching is intended to essentially speed things up. So it's either by avoiding recalculations. So it's kind of like another way to do memorization. You do the calculation once, you save the value somewhere, and then you reuse that same value instead of doing the calculation all over again. So that's one basic benefit of caching and you gave the example of avoiding some sort of a lengthy database query, but it could literally be any sort of computation. And the other is to get the data back from somewhere close and fast rather than going somewhere further and slower. So again, it could be getting the data from the local browser cache, which is obviously on your own device, rather than going over the network to get it from some server somewhere, which is going to take a longer time. Another example of caching might be even within your own computer itself. The CPU has a caching mechanism so that instead of going out to the slower RAM, it can actually get the cache data from a faster storage that's right, that's on inside the CPU itself. So all of these are essentially the same technique applied in various players and structures and places within computing. And we are going to talk about specific case of caching, which is caching on the web, which is either the browser caching a server response or a proxy server in between the browser and the server caching a response value, or maybe even the server itself, caching something in order to avoid recalculation. Is that, do you agree with our description, Vitaly?
VITALI_ZAIDMAN: Yeah, yeah, definitely. So I wanted to start when we talk about the browser cache, I wanted to start by talking about the cache control header, which is a header that basically when you make a request to the server, it describes to the browser how to cache their response. That's like in short, and it's really, really important to use cache control. And I'm going to explain why it's so important to use it. Because if you don't use it your browser has a heuristic. Your browser has some kind of default behavior and it determines how to cache things in a very, very unexpected way. And that is what I encountered a few months ago. Basically, if you don't have cache control, your browser looks at when your asset was less modify let say you request a dot jpg okay to an image and and the asset comes with a modified date that states that it was modified 100 days ago your browser will cache this asset automatically for 10 days so it's the difference between today and the last date when it was modified divided by 10 okay so you might be in a situation where you didn't want to cache anything and suddenly you see like your website doesn't update for some reason, things when your website doesn't update. And it happens because the browser has default behavior when it caches things. So it's very, very, I really don't advise using this method super intuitive. That's why we have the cache control header. And in the cache control header, we have many options that tell the browser how to act. So we can use private or public. Actually, I don't think we're going to talk about all of them. I think the most important of them is max age, I guess. It basically tells the browser that what you receive here is going to be stored for this and that amount of time on the browser and your browser will serve these assets from the browser without making any network request for that amount of time. Now it's super convenient and super fast, but it has its drawbacks because you might be in a situation where you want to update something, but it doesn't update. And it might be, you can catch things for a whole year in this way. So it's a really good thing to do, but also might be kind of dangerous.
DAN_SHAPPIR: So I'd like to give an example for that, if I may. So let's say I'm running some sort of an online news service, a newspaper or whatever. And I don't want, I get a lot of traffic and I don't want to overload my servers. And I also want to provide fast responses. So I could say, you know, usually I don't update my, my front page more often than once every 10 minutes. So I'll set the max age appropriately. And that way for I get this, I didn't, I'm sure that if the somebody visits the same, my, my site twice within that 10 minutes. They, the second visit won't actually load my servers because they'll use their local content. They'll also get it really fast. So they'll be happy, but then some breaking news happens and I update my site, but unfortunately it's, I updated it right at the beginning of that 10 minute cycle for somebody and they, they, maybe they heard from somebody that there's this really important thing happening. And they immediately refresh, try to refresh the site, but because of the way in which my caching is configured, they'll potentially get that same story all over again. And then because of that, they'll be disappointed with my site. They'll go somewhere else. And once they go somewhere else, there's a chance that they'll never come back. So you really need to be careful with these types of things. And, and that's, that's one example. Other, there are other examples where I potentially, I don't know, have bugs in my HTML because I deployed a new version and then to correct it. And I can't because, uh, people are using the cash version that has the bug. So, so, you know, there are all sorts of scenarios where caching can be problematic when you cannot remotely force a cache to clear.
AJ_ONEAL: I think that's the most problematic part.
CHARLES MAX_WOOD: You get a DMCA claim against, uh, an image or something on your website that you've told people to cash things like that.
AJ_ONEAL: I haven't had that.
CHARLES MAX_WOOD: I've had that on the podcast.
DAN_SHAPPIR: Yeah. That's definitely a scenario that the cash media.
AJ_ONEAL: Yeah. I think the biggest problem is when things break because of caching, because things are running at different versions. The front end is now running at a different version of the backend or the HTML is a different version than the JavaScript. That's where I see it being really problematic. The idea of static assets being cashed. I think this is good. The problem is that we don't want dynamic applications being cached so much.
DAN_SHAPPIR: Yeah. But the whole distinction between static and dynamic can become really tricky. Sometimes, I mean, because at the end of the day, everything is, I guess, is dynamic, it's just that the timeframes are different. Well, you can put it like that.
AJ_ONEAL: Yeah. I like the idea of how we used to do it back a decade ago, where you just hash the assets and then in the production version you just have the version of the file plus a dot and then the hash of the file or a truncated version of the hash of the file and then dot whatever the extension is. So you have main dot some random looking characters dot JS and main dot some random character, random looking characters dot CSS. I think that that worked out pretty well. And I don't, I don't quite understand why it seems like in the web and just in the world in general. Whenever people are at the pinnacle of success, that's when they just abandoned everything and go backwards.
DAN_SHAPPIR: Well, I have to tell you that actually that's exactly what we do with Wix. So when we consider static assets like JavaScript files or images, they all have CRC as part of their path. So as long as so and then we just set their cache to be like, like Vitaly said, for as long as the web essentially allows, which might be a year. Sometimes we set it a little less, but essentially from our perspective, they're immutable. And it's when something needs to change, what changes is the HTML itself, and the HTML is the thing that references the versions, or knows the different versions or CRCs that it needs to use. So we use exactly the method that you described, AJ. But we still can't don't get away from the fact that then it becomes a question of whether or not to cash the HTML itself
AJ_ONEAL: because never cash index.html and you'll never regret it.
DAN_SHAPPIR: Well, that's problematic because because because yeah, because then you start to get into all sorts of things like your time to first bite compares with the time to first bite of other type of solutions. And you know, we had the guests here talking about the gem stack recently. And part of the gem stack, for example, is pushing resources onto a CDN. So at the very least they're cashed on the CDN and the website itself, that it's version is, you know, it's not versioned in its HTML. So, so it's,
AJ_ONEAL: well, if you, if you use them react, you don't have to worry about that because there is no HTML in your index.html. It's just script.
DAN_SHAPPIR: Ah, yeah.
AJ_ONEAL: There you go.
CHARLES MAX_WOOD: Yeah, yeah, yeah, yeah. Problem solved. I mean, this is the part of it that makes it hard, or at least one of the things is that if you have a large index.html, or you have a lot of things that move around on the index.html or both, then it's okay, which parts do I cache? How do I cache? Can I cache on the backend in order to speed up the load, the work time on the backend so I can spit it up faster? And then, you know, on the front end, yeah, how do I let somebody know that something's updated so that they can get it with, but otherwise they get it faster. And yeah, there are a lot of things that go on here that I don't think there's going to be a one size fits all right. Where you kind of imply, just don't ever cash the index page. I don't know if that's realistic for everybody, but in some cases, yeah, it may be a terrible idea. And then in other cases, it may save you a ton of work on your server and it may be a better experience for your users. And so you have to be able to make that call.
AJ_ONEAL: Can we agree that caching falls within the realm of pre-optimization or not the realm of, but in the realm of risk of pre-optimization?
VITALI_ZAIDMAN: Oh, definitely. I think it's one of the most widespread pre-optimizations for sure. People are obsessed with caching before they even have a reason to do it like all the time. But if you're building a progressive web app, for example, you want to cache your index HTML because you want your users to access your websites when their phones are offline, right? But then what you're doing, right? Because like if your index HTML is cached and all the resources are cached, how do you even update your website ever? So one of the ways to do it is to use service workers where they first make a request. If it's not there, then they're using the cached version. But a very cool thing you can do, and obviously it doesn't fit all the websites, only some of them, is I guess you also on many web apps where you go to a website and it loads really fast and then shows you like some kind of pop-up jumps and tells you to refresh the page to receive a new version or to click the button to receive the new version. So basically they cache index HTML and they always serve it to you. They might even download the new version on the background. And the moment you click refresh, that's it. You receive the new version. So that's one way to do it.
DAN_SHAPPIR: Yeah. I think we kind of talked about some of this stuff also when we spoke with Jake Archibald from Google. I mean, I like to make a distinction between cache control, the cache control headers and the behavior of service workers. And they approach a problem from a completely different angle, and they should not be considered like replacements for each other exactly. Obviously, there's overlap. But with cache control, it's declarative. You tell the browser what you would like for it to do, and hope for the best. With service workers you literally implement the caching yourself. You write the caching code in JavaScript. You implement a client-side proxy and it's yours to do and yours to break. And the end result is that it gives you total control, but it also gives you the total ability to completely shoot yourself in the foot.
CHARLES MAX_WOOD: Yep. So when do you make the call? When do you start thinking about is this worth the trade-off?
DAN_SHAPPIR: Well, I can just say that from my perspective, first, my perspective is always get the cash control right. So regardless of whether or not you're going to be using a service worker from implement proper values in the cash control, because as Vitali correctly said, if you don't, you will likely fall into scenarios where the browser tries to make filling the gaps. And it's always beneficial to be explicit about these sort of things. And the control really at the point of the, of the initial decision-making, the control is at the hands of the server where it should be because the data is coming from the server. So the one providing the data has the most context about how long that data is fresh. Then if like Vitali said, if you want to have the ability to work offline, then you can introduce or do really sophisticated things that for some reason you can't do with the built in cash control headers, then I go ahead and implement a service worker. But then you better know what you're about and have really good testing because if you screw up caching, pardon my French, it's a very difficult problem to fix.
VITALI_ZAIDMAN: Yeah. I saw a collage a few days ago of like of Twitter threats where companies ask their users to refresh the page, like to do hard reloads, right? Because they're stuck in this scenario. And it happened a lot, like cases where people are starting to call support in panic and the support has to explain to sometimes hundreds of thousands of people or even more how to do this hard reload thingy. And trust me, that's a place where you don't want to be.
CHARLES MAX_WOOD: Yeah.
VITALI_ZAIDMAN: So, okay. So if you're talking about this extreme, yeah. Sorry, Chuck, I interrupted you.
CHARLES MAX_WOOD: No, I was going to start moving into some of the other areas because there are other things that I see people talk about when we talk about caches that yeah, anyway. So when you get to this extreme, what were you going to say?
VITALI_ZAIDMAN: Yeah. The other extreme is to not cash at all. So if you set your cash control to no store then it's not cached. And as Dan said, if you set it to no cache, it does something different, a little.
DAN_SHAPPIR: Can you explain maybe the difference between...
VITALI_ZAIDMAN: Yeah, yeah, I'll explain the difference. So, node-store makes sure that this particular request, whether it's a request to a server or to an asset or whatever, will not be cached anywhere. So, if you have some important thing, like, I don't know, a request if it has to do with banking or whatever, you don't want to cache it anywhere. Obviously it's not the only scenario, but so it's called no star. And if you use no cache, then it uses it tags and it makes it basically calls the server and asks it if the version that the browser has is the most fresh version. So how it works, the moment you download an image for the first time you receive not only images, any asset. The moment you download it for the first time, you receive status codes 200, and you receive an ETag. And this ETag is a unique ID that identifies your asset. So later you can make a request to the server and it sends this ETag along with the request that asks for this asset. And if the server sees that the Ethic didn't change. So basically you have the freshest version of an asset in your hands. Then it sends you the code 304, not modified. And basically it means that your browser can use the version that it has and it doesn't have to download the asset itself. Only the answer from the server that your version is fresh.
DAN_SHAPPIR: Yeah, I think that's the key to understand between the key difference between no cash and no store which is that no store like Vitali said, basically says, don't store a copy in your cache. You're not allowed to cache this content because I said so. Whereas no cache says, well, you can store the copy, but you're not allowed to use it before revalidating with the server that it's still fresh. And it might be, so an example that was given was using an ETag which usually is some sort of a checksum or CRC or whatever on that resource. So if it stayed the same, it's the indication that the version that you have is still fresh and still usable. Of course that eTags are optional. I mean, you don't, the server can send down an eTag or it can't send down an eTag, it doesn't want to.
CHARLES MAX_WOOD: Yeah. It's just something that comes in the header, right?
DAN_SHAPPIR: Yeah, it's, it's another field in the head in the response header. Yeah. For example, if, if we go back to the example of immutable resources, resources that never change. Like we talked about static resources, like an image that maybe has a CRC as part of the URL itself, where there's no point in also sending the CRC down as an e-tag because it will never change. So why check if it's changed?
VITALI_ZAIDMAN: Just the word about CRC. So basically, we want to use content hashes. We want to, even if we, for example, even if our website has changed, but several files didn't change, we want to use hashes on file names. So it's filename.somekindofhash.extension that represents this particular version of this file. So if the file didn't change, you still receive the same content hash.
DAN_SHAPPIR: And Webpack does that for you, I think, right?
VITALI_ZAIDMAN: In Webpack, when you output your files, you can, if you use like a file loader, you can choose between content hash and basically just a hash. And hashes are created faster than content hashes, but they're less reliable.
CHARLES MAX_WOOD: Yeah. The way I use Webpack or the way I have configured, I've been getting the hashes. I know that a lot of frameworks will do it for you too, if they have some other pipeline for managing status, static assets.
VITALI_ZAIDMAN: Yeah. In Next.js, for example, you can configure. Next.js to use eTags automatically. So it's, uh,
CHARLES MAX_WOOD: yeah, Rails does it too. You can turn on eTags.
VITALI_ZAIDMAN: Yeah. And it works like from the client side and also from the server side. So it's really nice in the Next.js.
AJ_ONEAL: I assume there's a way to turn off eTags and Express.js. They are on by default.
VITALI_ZAIDMAN: Yes, there there's yeah, exactly. There, there's a way to turn it off.
DAN_SHAPPIR: Yeah, look, it doesn't usually do any harm. I mean, the browser just remembers that value that it got in the response header and sends it back in the request. The server doesn't need it because it knows that the content never changes. It can just ignore it. It can always just ignore it, by the way. It's totally the server's decision what to do about the ETAC.
VITALI_ZAIDMAN: The only drawback I can think about is that generating ETACs might be a little costly, but I think if you have this problem, you probably have a very, very unbelievable traffic.
AJ_ONEAL: So I don't think that e-tags would generally be costly because usually you're using something like a SHA sum and the CPU cost of doing a SHA sum on content is typically very minor.
VITALI_ZAIDMAN: Yeah, probably. Even for like huge assets, I don't know, megabytes, whatever.
AJ_ONEAL: Well, the asset was going to be served anyway.
DAN_SHAPPIR: Yeah, and it's going to be compressed likely anyway. So, you know, calculating a SHA sound is cheaper than compression.
AJ_ONEAL: And there are constant time hash algorithms. I don't know what the default is in Express JS, but it would make sense. I don't know if web servers are doing this or not. I'd have to check into it to actually look at code or specifications, but it would totally make sense to use constant time hashes for eTags where it only samples say. Typically, you know, you can look at heuristics. You can say the first kilobyte of a file and the last kilobyte of a file are the parts that are most likely to change. Cause that's where metadata is. And if you sample the first, the last, and then maybe two or three in the middle, you could just read in four or maybe eight kilobytes and have a 99.99% accuracy as to whether or not a file has changed.
Did you work your tail off to get that senior developer gig just to realize that senior dev doesn't actually mean dream job? I've been there too. My first senior developer job was at a place where all of our triumphs were the bosses and all the failures were ours. The second one was a great place to continue to learn and grow only for it to go under due to poor management. And now I get job offers from great places to work all the time. Not only that, but the last job interview I actually sat in was a discussion about how much my podcast had helped the people interviewing me. If you're looking for a way to get into your dream job, then join our Dev Heroes Accelerator. Not only will we help you get the kind of exposure that makes you attractive to your dream employer, but you'll be able to ask them for top dollar as well. Check it out at devheroesaccelerator.com.
CHARLES MAX_WOOD: Yeah, well the other thing that I see happen sometimes, and this is something that Rails does in particular, is that if it renders a partial part of the HTML then it can generate kind of a fragment hash and work off of that. The other thing that I've seen it do is use a hash on the object as opposed to a hash on the generated HTML as a stand-in and actually skip all of the rendering and then be able to generate that ETAG even more quickly, right? So if the HTML request is just loading in a page that only renders basically the information off of that one object, then yeah, it doesn't need to go through the render steps. It knows whether or not it needs to clear the cache based on whether or not that object has changes in it or any of the objects that it's composed from has changes in it. And so it'll kind of cheat and not do the rest of the work and then hand down an E tag or a hash that's already telling it, hey, this is all the same, right? And then you can have JavaScript or something else on the front end, stimulus or react or something like that that will come back and actually update like anything that looks like a feed or anything that needs to pull extra information from the site later on.
DAN_SHAPPIR: But an important thing to remember when using e-tags is that yes, it can say, avoid the, the data download, because if the e-tag doesn't change, like Vitaly said, you just get a three or four response that says basically use what you've got, but it does not avoid the round trip to the server. And if you're, let's say on some mobile device and some sort of a slow network, because I don't know, you're traveling overseas or whatever, that, that duration can be lengthy in and off itself. So it's, it's not like you're going to get instant response because you're quote unquote, caching. There's still a price to pay when you're relying on, on data that requires revalidation.
CHARLES MAX_WOOD: That's true. Thanks for clarifying that.
DAN_SHAPPIR: Which brings me to another point that I wanted to ask you. So we covered three cashe directives, no cash, no store, max age. Are there others that you want to mention and cover?
VITALI_ZAIDMAN: Yeah. So we have public and private and they determine if an information is private for that single user only, which is the private one, and it would not be stored in shared caches. There are more caveats caveats to it, but when you cache things, just remember that you don't want to cache things on places where you're not allowed to cache it or where it might be problematic to cache it. I think Chuck, you talked about one of these cases, right?
DAN_SHAPPIR: Can you give an example of or describe the difference between a private and a public cache?
VITALI_ZAIDMAN: Yeah, for example, if I have a private picture that the user uploaded, you want to save it in a private place. For example that's the most obvious one.
DAN_SHAPPIR: But I also mean what is a private cache versus a public cache. I mean that, for example, like a private cache would be the cache in your own browser, on your own device, in your own session or operating system session. So that would be a private cache for you. But if there's like a proxy in the middle and it caches the response that's a public cache because theoretically it could be used by anybody who's going to that proxy, right?
VITALI_ZAIDMAN: Yeah. I wonder if a private cache can also be on the web somewhere.
DAN_SHAPPIR: Well, theoretically I could construct a private cache, but that would assume assume that I know exactly who the user is that is going through that connection. If I, if I was able to totally validate that user you know, then I could also have a private cache in the cloud. I'm not sure that there would be value for that because if I can, well, maybe I know if a user potentially switching between devices, then I could theoretically cache across devices for that user that could be, that could be interesting. Yeah. You could have theoretically a private cache in the cloud. Why not? In the context of private, of a private and public cache, I think it's also worthwhile to mention the S max age setting, which is similar to max age, but actually controls, overrides max age for shared caches. So you could actually use it to specify different durations for content in a private cache versus a public cache. And what always gets me is that max age is written max dash age, but S max age is written as dash max age without a dash in the middle of max age, just to confuse us all. And believe me, I've seen cases where people wrote it wrong.
VITALI_ZAIDMAN: Yeah. I also wanted to just remind you, I just wanted to remind you that Internet Explorer works differently. So just take it into account and if you need to support it, then read about how it works.
STEVE_EDWARDS: That is shocking. Say it isn't so. Yeah.
VITALI_ZAIDMAN: I will add the link actually that explains how Internet Explorer works with cash control for people like me who struggle to make sure that things are supported there.
DAN_SHAPPIR: Even Microsoft is end of life to Internet Explorer. How long do we need to continue to support it?
CHARLES MAX_WOOD: As long as enough of your users are using it.
VITALI_ZAIDMAN: As far as I understand some government entities still use Internet Explorer 8 and 9. So I don't know man.
DAN_SHAPPIR: Some government entities still use Windows Vista, but yeah, it's sad. I do have to give props to Microsoft in this regard that the new Edge can be installed on older Windows operating system versions, unlike the old Edge, which could only be installed on the very latest Windows versions. I know that that's a somewhat confusing statement, but thanks to that, you can actually deploy Edge as a replacement for Internet Explorer on older Windows devices. And before we run out of cash control settings, I have to also discuss the partially experimental stale while we validate setting, which I think is amazing and partially eliminates the needs for service workers in some cases.
CHARLES MAX_WOOD: Okay, well, what is it then? Cause I like service workers. I think they're cool. They're kind of a pain sometimes, but they're cool.
DAN_SHAPPIR: Well, I like them as well. And I said, in some cases, the idea would stay while we validate basically means that if you've got a version of that resource, which is state, which means that, you know, it's, it's potentially outdated. And in the past, you would like we talked about, you would send a request maybe with an e-tag. And then the server could tell you, yes, you can keep on using it even though it's old, or it would say, no, here, use this version instead. But the cost is that at the very least, you've got the delay of the round trip, which as we mentioned could be even if it can be non-trivial. And if a new version needs to be downloaded, well, then you need to wait for the new version to arrive you set the request for the fresh content in the background and continue using the stale content just this time. So let's say you visit, we were giving that example of that newspaper. If you have stale while we validate, you will show the previous edition. But the next time you load it, you will get the new edition because it sent the request and got the new edition in the background while you were reading the older version. So you get this benefit of a really fast response and about the guaranteed freshness for the next time. And the setting is stale while we validate with equals a number, which basically just tells you how long you can still use that stale version. If that time expires, then you need to wait for the new version to arrive before showing it to the visitor.
VITALI_ZAIDMAN: Yeah, it might be amazing. I think I really would like to use it. Sure.
DAN_SHAPPIR: Yeah, obviously you need to be careful with that because there are scenarios where it's not a good idea. For example, I don't know, let's say you're showing your bank balance to somebody. It's not a good idea to show your old bank balance.under any circumstances. So, yeah, even with that sort of a setting, you need to be careful. But it's definitely a way, if you're okay with serving an old version like that one time, then it could potentially provide a really significant performance boost very easily and fairly cheaply.
VITALI_ZAIDMAN: I think we can see something like this with profile pictures sometimes. If you receive the old one, even though updated your profile picture already but on your next next time you look at it it's already it's already updated.
CHARLES MAX_WOOD: I don't know do you know how long Steve Edwards spends grooming for his profile pictures and he updates it like six times a day.
STEVE_EDWARDS: It's hard to groom when I have no hair but unless there's other things we need to talk about.
DAN_SHAPPIR: Oh you've got the eyebrows no?
STEVE_EDWARDS: Yeah I got to film those once in a while that's about it. Shave every few days I'm good to go.
CHARLES MAX_WOOD: Yeah there you go. All right. Any other aspects to this? One other thing that I was wondering about is CDNs, right? So I keep hearing CDNs, but then you don't always have control either on like cash and validation and stuff like that, right? Because
STEVE_EDWARDS: somebody else wants to CDN real quick, Chuck. Content Delivery Network.
CHARLES MAX_WOOD: Thank you. I'm like, I was like, it rolls off my tongue until you ask me. And then. And what is the CDN?
STEVE_EDWARDS: And what is the CDN?
DAN_SHAPPIR: So really, Steve, what you were doing is wasn't really asking, Chuck. You were giving you were like.
CHARLES MAX_WOOD: Pop quiz,
DAN_SHAPPIR: exactly.
STEVE_EDWARDS: Well, no, I wanted him to explain it, but I assumed he knew what the letters meant. I guess I was wrong.
CHARLES MAX_WOOD: So essentially, yeah, it's a place up in the cloud that's usually a set of distributed servers across the globe where you can put your static assets so that people theoretically can download the assets from a server that's closer to them, shortening the round trip and thereby making the thing load faster. That's the theory.
DAN_SHAPPIR: And to add to that, they usually operate as a series of proxies. So once you put the content somewhere, then it gets replicated or you go through to the servers up to the level where that content exists. But when, when it downloads the stuff, it keeps a copy of it. So like I said, it's a proxy and we talked about shared storage. That's exactly the example of shared storage caching.
CHARLES MAX_WOOD: Yeah. In fact, most of the CDNs that I've used they'll keep a fresh copy of the stuff that you tell them to. But then in a lot of cases, they'll move stuff that doesn't get hit as often. So as long as it's getting repeatedly and frequently downloaded, they'll keep it in the cache, right? Because they want to serve it quickly. But if it's not, then a lot of times they'll move it to a slower cache basically, or to hard disk.
DAN_SHAPPIR: Yeah, but that's true. Yeah.
VITALI_ZAIDMAN: There are usually a lot of configurations on CDN. Yeah. You know, this type, like for example, some CDNs invalidate assets after they've been in their own cache for like, I don't know, two days or three days or a week. And then when the next user makes a request, it refreshes the asset only then.
CHARLES MAX_WOOD: Yeah, in fact, most media services for podcasts work this way, except for them, it's when the episode is published they'll hold on to it for a week and then they'll move it to their slower system. Because most downloads happen within that first week.
DAN_SHAPPIR: Yeah. That's the thing to realize about caching is that at the end of the day, you can't rely on caching actually happening. You're telling the system that you would like for it to cache the content. You're telling the system for how long it's allowed to cache the content, but it can always decide to just not to cache or to cache for a shorter duration because like you said, maybe it's run out of storage, it wants to keep something else instead, it's not frequently requested content, so it decides that there's really no point in caching it. For any one of those reasons or another, it might just not cache that content.
CHARLES MAX_WOOD: Right, the difference though, is that all of the cache control settings, all of the ETAG stuff, all of the stuff that we've been talking about, you can throw into the header, you can control that if you control the system that it's hitting, right? So you can set all that up in Nginx or Apache or Express or whatever. But when you move to a CDN, you don't have those controls anymore unless they give them to you.
DAN_SHAPPIR: On the other hand, I do know that the CDNs often, very often do give you the ability to force a refresh, which is something that you cannot do with the browser cache. So it's like there's, there's benefits, pluses and minuses.
CJARLES: Yep. Absolutely.
VITALI_ZAIDMAN: Yeah. By the way, another different aspects of caching is that from what I've seen, people often cache assets, but they don't cache requests. So you can cache many things on the CDN. You can cache requests that are not often updated, for example, and you can cache even if you use server-side rendering, for example, it might be a good idea to cache the response from the server-side rendering if you can if you don't have anything dynamic there, for example. So consider the things.
DAN_SHAPPIR: Yeah, we actually talked exactly about that in a recent podcast episode when we were talking about the JAM stack. About the JAM stack usually generating content and pushing it into CDN at build time. And then you're cashing off, you're potentially indefinitely cashing off of the result of a build. But you could also use a different strategy like you just described, where you're using server-side rendering. So the first time that the content is requested, only then at runtime, do you actually generate that content and then you push it into the CDN and it's cached from that point on. So yeah, you could use various sorts of caching strategies with it on the server side, on the backend side, for sure.
CHARLES MAX_WOOD: Is there anything else that somebody else wants to bring up before we move ahead.
STEVE_EDWARDS: And maybe this isn't directly related, but indirectly related to tangent, shall we say. When we're talking about CDNs and some of the things you can do on CDNs, I know that I've heard someone like Wes Boss talk about things like Cloudflare workers or basically code that you can run on the CDN to intercept requests as they come and before they get all the way back to the base of your application. Vitaly, I'm just curious to see if you're use these before or if they can be used within a caching structure or if my just completely off based on something irrelevant.
VITALI_ZAIDMAN: I'm not sure if you're talking about what I'm thinking about, but from what I saw, you can configure the CDN to cache even dynamic content in many cases. If, uh, like smart CDNs can cache dynamic content based on, uh, like headers and like, uh, things that you return to the user. So that's what I saw.
DAN_SHAPPIR: Yeah, we actually use that kind of, again, which is big enough that we more or less try everything. And we also used this sort of functionality of computation at the edge. It's kind of adjacent to caching, I would say. The basic idea is that it just does the computation closer to the endpoint. And in a more distributed sort of a way. And if and when you can do that, it means that you don't need to go as far in order to get the data. And also, the computation is distributed across more servers, so it also can happen. It addresses scalability issues. But I look at it more as something that's adjacent to caching, and not necessarily, I won't necessarily put it in the same bucket. I would like to mention one more thing, and that sometimes like we said that I gave one example of that or made a statement that you can tell a system how long you would like for something to be cached and according to what strategy, but it may do something else. It might decide to cash it for a shorter duration. Well, I would like just to mention that in some few cases, you might tell a system not to cash something and it would still cash it. So we gave an example before that when you say no store, you're literally telling the browser, don't cache this. Well, it turns out that in some cases, the browser will cache it despite you telling it not to cache it, at least for really short duration. For example, if you prefetch a resource, even if that resource is marked as no store, it will be kept in a memory cache for a few minutes because otherwise prefetching would literally have no effect. So it's amusing how this is a really weird and wacky world where we try to really control all the possible scenarios with, you know, declarative sort of a way. And then it turns out that we run into all sorts of sophisticated edge cases and whatnot. So, and, and
VITALI_ZAIDMAN: yeah, the other scenario is what, what you see if you don't use cache control at all thing that I started with because for the first 10 days you will not have cash at all usually and then after a few weeks your assets will you will see that your assets are actually cashed for a short amount of time and after like a month or so they'll be cashed for a few days and so on so it's a very very confusing behavior and that's what essentially happened to me I saw assets that's look exactly the same. I couldn't understand what's the difference between them. Why some are cached and some return 304 and use eTags. And that was the difference that for some reason, cache control disappeared and we had to reconfigure it.
DAN_SHAPPIR: Yeah. One of the things that, you know, when I'm asked to review a site, either for performance or in general, even one of the first things that I do is look at the, the, the cache control response headers for the resources. And very often they're not what they're supposed to be. And it's a fairly quick win when you're able and easy and cheap win when you're able to get the proper behavior just by a slight change to the server response.
VITALI_ZAIDMAN: I think it's one of the things that fall between the chairs and many organizations because from the one hand, the front end developers are using the assets and usually they also upload them. But from the other hand, the backends don't really care about it in many organizations. Like it's not in their, it's not their part. So what happens is that your caching is not configured and it works weirdly. Probably it hurts your performance. Probably it costs you because your servers are used more instead of storing things on the user's computer. And it's something that I really encourage everybody to get to know because I know that there's very little awareness of how things work. Oh, and mozilla.org, the HTTP caching section about the whole thing that I will add to the resources of the episode. They're amazing. Just read the whole thing from start to end and you will know pretty well how caching works.
DAN_SHAPPIR: I think what you just said about how this can fall between the chairs is an amazing excellent point. I think we kind of hit the nail on the head here. I've definitely seen that type of a scenario. And in addition to that, very often, even if you have end to end tests, they won't identify caching problems because usually end to end tests use a fresh client, they, they spin up, let's say a puppeteer instance or something like that. So caching doesn't even come into play. So, so yeah. It's definitely something that you that can be easily overlooked and really bite you if you don't properly configure it.
VITALI_ZAIDMAN: Also because recommend if i'm wrong then but google mostly cares about like the load speed of your website So many people don't really care about the second time a user enters your website. Because of this reason.
DAN_SHAPPIR: Yeah that we we will probably do an episode about that in the future. People are now all hot to trot about performance because it's going to be an SEO ranking factor. We even had Martin Shpley to talk about it here from Google. But the reality is that as a ranking signal, it's probably going to be a fairly minor signal. People should care about performance because their visitors are impacted by performance. So even regardless of how well you rank, if your site has bad performance, you will get a high bounce rate. People will just abandon your site because it's slow to load.
VITALI_ZAIDMAN: Yeah, it's empirically proven by like once and again by many great companies.
DAN_SHAPPIR: Exactly. And having proper cache configuration on the one hand is a great way to improve performance and having an improper cache configuration is a great way of displaying wrong data and potentially having all sorts of privacy issues if you're not careful.
AJ_ONEAL: Now I was under the impression that Google was actually backtracking some on ranking sites. I guess it was mobile performance. I read an article where they're not going to rank sites as heavily based on mobile performance because what's the name of the law? Whatever measuring something as a metric, it becomes less useful for the thing for which you were measuring it. People are abusing it and causing sites to be worse. And so Google's actually scaling back on it.
CHARLES MAX_WOOD: Yeah. I don't know what that law is, but yeah, it makes sense though, right? They tell us they're measuring it and so everybody starts gaming it. All right. I've got to start us wrapping up because I have a call at noon and I've got to feed my daughter between now and then so that that gives us like 12 minutes. Let's go ahead and do picks.
Hey folks, if you love this podcast and would like to support the show, or if you wish you could listen without the sponsorship messages, then you're in luck. We're setting up new premium podcast feeds where you can get all of the episodes released after Christmas 2020 without the ads. Signing up will help us pay for editing and production, and you can go sign up at devchat.tv slash premium.
CHARLES MAX_WOOD: Dan, are you in a position to do picks? Looks like he's not. Vitaly, do you have some? Oh, we'll do you last because we always do the guest last. Steve, do you want to do some picks for us?
STEVE_EDWARDS: I did want to point out that we have a little document that we used to gather notes for what we're going to talk about. And I had put some questions that got skipped. So I'll read one of them now. And this is very relative to caching and it says, do sheep shrink when it rains? And so I actually have an answer to that. There's a great YouTube video that I found a number of years ago by a channel called Minute Earth. And it goes into great detail about why don't sheep shrink when it rains as compared to wool shrinking in the dryer. It goes into detail about how the hairs rub together and the friction causes the drying, causes the shrinkage in the dryer versus when it's just out in the rain. So it's only a couple of minutes long, but it's a very good scientific answer to the question that I know many people have lost sleep over at night. And then my other two jokes for the day, or for the week, excuse me. One comes from Pun Bible and it's just a simple question that says, why are they called territorial disputes and not ground beef? something to think about, right? And then standup t-rex has a good question about who is the patron saint of homeless dogs and cats? And it's Saint Ray, you know, Stray, Saint Ray. Anyway, those are my jokes for the day. And just a side note, hey, Alan, I hope I sounded more like a smart guy than just the funny guy today. So I'm done.
CHARLES MAX_WOOD: All right, AJ, what are your picks?
AJ_ONEAL: All right, well, I got a couple of good ones as always. First off, since we did touch a little bit on Cloudflare. I think that's the name for them. So I'm going to link y'all to a video that was, it's a presentation part of Utah Rust that has to do with Cloudflare workers and Wasm and Rust. Cloudflare workers is not in the title of the video, but it is the example that was, was being given for how to use basically node through Asm on Cloudflare. And then I'm also of course going to pick. Beyond code bootcamp for those of you that are interested in leveling up on your coding skills I do live streams almost every day except I'm on vacation right now and have terrible internet so I haven't been able to to do that this week but in general, I've got live streams going every weekday and I've got links in the show notes here for Facebook YouTube and Twitter If you've got any questions that you'd like me to answer or cover in a video at underscore beyond code on Twitter would be a great place to do it and then I really think that it's important for people. I was doing something on resumes recently, you know, have a website where you put up your resume. Don't just hang it off of GitHub pages. Go that little bit of extra effort to have something that, you know, has a little bit better branding for yourself that goes on, on your resume and whatnot. And I, I have an affiliate link for name.com. And it's in, I'm going to put the video for both when I'm going over how domains work and I have an affiliate link for name.com there, and then the, there's a video on how to set up your first server. And there is an affiliate link for two months free or a hundred dollars free on digital ocean there as well. So that's, that's all my stuff for today.
CHARLES MAX_WOOD: Awesome. All right. I'm going to jump on with a few picks of my own. The first one that I have is, I'm just going to remind you all about the Dev Influencers Accelerator. If you're looking to kind of take your career to the next level, usually it's people trying to get into kind of a second career where they're, they're replacing their full-time income, um, making a difference for the dev community and being recognized as an expert while doing it. Let me go check it out at devinfluencers.com slash apply. And that'll take you to a page where you can actually apply to be part of the accelerator. The reason I make you apply is I just want to make sure that it's a good fit. Not everybody's in a real good position for that. And I don't want people to go sign up and then, you know, have to back them out. If they're not a good fit, I'd rather just talk to people and help them get ahead. If they're not a good fit by giving them advice on where to go next. The next pick that I have, I've been listening to this book called fanatical prospecting, I've been kind of on a sales kick lately, and I've really been enjoying that just talks about how to keep finding people to sell to. I do this for sponsorships. I do it for the accelerator. And it's really terrific. And then the last pick I have is Riverside FM. That's the system we're probably going to be moving to here within the next month to record on. It actually puts everybody on their own channel. It works through the web browser. It is so nice. There are a couple of kinks I have to figure out because you can only have one show recording on one account at a time. And most of our shows don't occur concurrently. So it's not major issue. The only shows that are possible collisions are She's in Tech, which is our women in tech show. And, and I just have to make sure that they're not recording with somebody else's really. So I'm going to pick that as well. And yeah, that's pretty much it for me. Vitali, what are your picks?
VITALI_ZAIDMAN: All right. Well, well, Dan said there were sirens and it might mean that they all had to go cover.
CHARLES MAX_WOOD: So, Oh, that's right. That's what going on there. Yeah. And I don't know. I don't know if it was both of them or just one of them. There's a lot going on over there. All right. Well, we'll go ahead and wrap up here. Big thanks to Vitali for being here and until next time, folks, Max out.
STEVE_EDWARDS: Adios.
Bandwidth for this segment is provided by Cashfly, the world's fastest CDN. Deliver your content fast with Cashfly. Visit C A C H E F L Y.com to learn more.
Mastering Browser Caching with Vitali Zaidman - JSJ 490
0:00
Playback Speed: