Adding a cachebuster with a Git post-receive hook
Published on .
For a long time the caching on my weather webapp has been broken. This HTTP Caching article from Google finally helped me understand what was wrong. So, at last, here is a simple solution to add a cachebuster to the stylesheet!
### hooks/post-receive
#!/bin/bash
md5=`cat style.css | openssl md5`
sed -i -r -e 's/(<link rel="stylesheet" href="style)\.css/\1.'${md5: (-6)}'.css/' index.php
echo "Added cachebuster to stylesheet link."
### .htaccess
RewriteEngine on
RewriteRule style\.[A-Za-z0-9]{6}\.css$ style.css
Code language: Python (python)
The problem was that when I updated the stylesheet, the clients would still use the cached version.
To solve this, the simple and obvious answer is a cachebuster, but that seemed too hard for there must be a way to do it server-side! And for far too long, I mucked around with adding cache-control
headers to the .htaccess
, but finally this passage made it clear that this is hopeless for invalidating from the server-side:
However, what if you want to update or invalidate a cached response? For example, suppose you’ve told your visitors to cache a CSS stylesheet for up to 24 hours (max-age=86400), but your designer has just committed an update that you’d like to make available to all users. How do you notify all the visitors who have what is now a “stale” cached copy of your CSS to update their caches? You can’t, at least not without changing the URL of the resource.
https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/http-caching
OK, great, but that leaves me with a workflow problem. Am I really going to remember to update the stylesheet URL every single time I modify the stylesheet? And do I really want that in the git log?
I wanted to avoid a query parameter, because I heard some caches are actually smart enough to realize that its still the same resource.
So, changing the filename made sense, which would require two things:
- Include a hash of style.css in the
<link>
tag for the stylesheet - Configure a
RewriteRule
to pointstyle.<hash>.css
back tostyle.css
So, after some tinkering, I arrived at the above solution. Now my app “loads” in just 60 ms when it is cached and my server properly responds with a 204 for the index but most importantly, when I modify the stylesheet the new version is retrieved!