diff --git a/config.toml b/config.toml index 1e261de..aa7923b 100644 --- a/config.toml +++ b/config.toml @@ -62,7 +62,7 @@ images = [""] # Home subtitle of the index page. # homeSubtitle = [ - "Hi! I'm a Software Engineer at Dendron, and a recent Master's graduate from the Ohio State University. I'm an avid Linux user, an enthusiast of many programming languages, a home cook, and an amateur gardener.", + "Hi! I'm a Software Engineer, an avid Linux user, an enthusiast of many programming languages, a home cook, and an amateur gardener.", "My interests include building web and mobile applications, both front and back end. Over the years I learned and used many programming languages and technologies, including JavaScript, TypeScript, React, React Native, Python, Java, C, C++, Clojure, Rust, and Haskell. Pretty much everthing I've worked on is open source and available on my Github page.", ] @@ -171,7 +171,7 @@ url = "https://github.com/SeriousBug/" [[params.social]] name = "mastodon" -url = "https://mastodon.technology/@kaan" +url = "https://fosstodon.org/@kaan" me = true [[params.social]] diff --git a/content/img/browser-caching-after.png b/content/img/browser-caching-after.png new file mode 100644 index 0000000..6145092 --- /dev/null +++ b/content/img/browser-caching-after.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:50d32e24aacb1ce97ca3f5462d5efb8be048d6066e85751a01cd58b9689909df +size 78106 diff --git a/content/img/browser-caching-before.png b/content/img/browser-caching-before.png new file mode 100644 index 0000000..4e51cd3 --- /dev/null +++ b/content/img/browser-caching-before.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dd0f5a04f63cdef5b74fc958119540cb916e1a95ac00e43558afeb5d899dcbc5 +size 29473 diff --git a/content/posts/2022.10.15.browser-caching-304-assets-not-revalidated.md b/content/posts/2022.10.15.browser-caching-304-assets-not-revalidated.md new file mode 100644 index 0000000..1d6570e --- /dev/null +++ b/content/posts/2022.10.15.browser-caching-304-assets-not-revalidated.md @@ -0,0 +1,47 @@ +--- +title: "Browser Caching: Assets not revalidated when server sends a 304 'Not Modified' for html page" +date: 2022-10-15T20:56:36-04:00 +toc: false +images: +tags: + - dev + - web +--- + +I've been working on some web server middleware, and hit a weird issue that I +couldn't find documented anywhere. First, let's look at an overview of how +browser caching works: + +If your web server sends an +[ETag](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/ETag) header in +a HTTP response, the web browser may choose to cache the response. Next time the +same object is requested, the browser may add an +[If-None-Match](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/If-None-Match) +header to let the server know that the browser might have the object cached. At this point, the server should respond with the +[304 Not Modified](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/304) +code and skip sending the response. This can also happen with the +[Last Modified](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Last-Modified) +and +[If-Modified-Since](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/If-Modified-Since) +headers if `ETag` is not supported as well. + +After implementing this in my middleware, I made a quick test website to try it +out. That's when I ran into a weird behavior: the browser would revalidate the +HTML page itself with the `If-None-Match` header, but when the server responded +with `304` it would not attempt to revalidate the linked stylesheets, scripts, +and images. The browser would not request them at all and immediately use the +cached version. It looks like if the server responds with `304` on the HTML +page, the browser assumes that all the linked assets are not modified as well. +That means that if the asset does change (you weren't using something like +fingerprinting or versioning on your assets), then the browser will use outdated +assets. Oops! + +Luckily it looks like there's an easy solution: add `Cache-Control: no-cache` +header to your responses. `no-cache` doesn't actually mean "don't cache at all", +but rather means that the browser needs to revalidate objects before using +the cached version. + +Without the `Cache-Control` header: +![Browser developer tools window, there is only 1 request for /](/img/browser-caching-before.png) +With the `Cache-Control` header: +![Browser developer tools window, there are 5 requests in total, including /, style.css, and 3 images.](/img/browser-caching-after.png)