Nat TaylorBlog, Product Management & Tinkering

Adding a cachebuster with a Git post-receive hook

Published on . Updated 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

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:

  1. Include a hash of style.css in the <link> tag for the stylesheet
  2. Configure a RewriteRule to point style.<hash>.css back to style.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!

Popular Posts

Post Navigation

«
»