Compare commits

...

2 commits

Author SHA1 Message Date
Kaan Barmore-Genç 9d5d602c04
Add woodpecker
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2022-11-19 01:39:32 -05:00
Kaan Barmore-Genç 9cf4164f88
Browser caching article 2022-11-19 01:04:59 -05:00
6 changed files with 69 additions and 7 deletions

5
.gitmodules vendored
View file

@ -1,6 +1,3 @@
[submodule "themes/hello-friend-ng"]
path = themes/hello-friend-ng
url = https://github.com/rhazdon/hugo-theme-hello-friend-ng.git
[submodule "themes/catafalque"] [submodule "themes/catafalque"]
path = themes/catafalque path = themes/catafalque
url = git@github.com:SeriousBug/hugo-theme-catafalque.git url = https://github.com/SeriousBug/hugo-theme-catafalque.git

12
.woodpecker.yml Normal file
View file

@ -0,0 +1,12 @@
clone:
git:
image: woodpeckerci/plugin-git
settings:
recursive: true
pipeline:
build:
image: klakegg/hugo:ext-alpine
commands:
- hugo -D
- ls -lAh

View file

@ -62,7 +62,7 @@ images = [""]
# Home subtitle of the index page. # Home subtitle of the index page.
# #
homeSubtitle = [ homeSubtitle = [
"Hi! I'm a Software Engineer at <a href='https://dendron.so'>Dendron</a>, and a recent Master's graduate from <a href='https://osu.edu'>the Ohio State University</a>. I'm an avid Linux user, an enthusiast of many programming languages, a <a href='/recipes'>home cook</a>, and an amateur gardener.", "Hi! I'm a Software Engineer, an avid Linux user, an enthusiast of many programming languages, a <a href='/recipes'>home cook</a>, 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 <a href='https://github.com/SeriousBug/'>my Github page</a>.", "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 <a href='https://github.com/SeriousBug/'>my Github page</a>.",
] ]
@ -171,7 +171,7 @@ url = "https://github.com/SeriousBug/"
[[params.social]] [[params.social]]
name = "mastodon" name = "mastodon"
url = "https://mastodon.technology/@kaan" url = "https://fosstodon.org/@kaan"
me = true me = true
[[params.social]] [[params.social]]

BIN
content/img/browser-caching-after.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
content/img/browser-caching-before.png (Stored with Git LFS) Normal file

Binary file not shown.

View file

@ -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)