Hugo Minification

Since moving my site to hugo, I have only a handful of things left on my todo list. Once of them was bundling and minifying the files I serve so that I can properly push them with HTTP/2 push, and so that on HTTP/1.1 clients the site is as snappy as it can be (there’s also some argument to be made that bundling the files is an anti-pattern with HTTP/2, but I haven’t actually verified the data either way). None of this is really required, as my site is fairly lightweight by modern standards (though one day I’d very much like to work out if there’s any parts of bootstrap I can live without as my CSS bundle is still about 110KB which seems ludicrous to someone who was an active internet user in the 90s).

So Hugo Pipes looks the go, and while the documentation is fairly terse it doesn’t seem all that difficult. I threw together all the things I wanted, gave it a shot and… it didn’t work. It seems resources.Get only looks in the “assets” directory, my “assets” are in “static” (a leftover from the theme I borrowed as a starting point to write mine), so it couldn’t find them. Shift those over, and it works! The final template code:

		{{- $bootstrapCss := resources.Get "css/bootstrap.min.css" }}
		{{- $bootstrapFontAwesomeCss := resources.Get "css/font-awesome.min.css" }}
		{{- $bootstrapOverrideCss := resources.Get "css/override.css" }}
		{{- $css := slice $bootstrapCss $bootstrapFontAwesomeCss $bootstrapOverrideCss | resources.Concat "css/darkstrap.css" | resources.Minify | resources.Fingerprint "sha384" }}
		<link rel="stylesheet" href="{{ $css.Permalink }}" integrity="{{ $css.Data.Integrity }}" />

The resulting output:

		<link rel="stylesheet" href="http://localhost:1313/css/darkstrap.min.6c443406845f5793e7d2b714bc008d5d923d826cc07b7f5e62ff611057e3a84e8bbafe987dded7309d7db365986d66f1.css" integrity="sha384-bEQ0BoRfV5Pn0rcUvACNXZI9gmzAe39eYv9hEFfjqE6Luv6Yfd7XMJ19s2WYbWbx" />

The only trouble with this is that goddamn cache-buster in the file path. That’s probably desirable for some folks, however I make almost zero changes to my theme pretty well ever… I’m much more likely to throw the entire thing away and start anew than I am to make any sort of breaking change to the file. Importantly, as I hand-write the URLs to HTTP/2 push in my server configuration, I need the files to be in a predictable location. If I do make any changes to the file, I’ll blow away my CDN cache and it probably doesn’t matter if the file stays cached on the user’s browser for a while afterwards (though I’m not sure if SRI will affect that?)… I’m in the unique position where I need the ability to instantly invalidate the caches much less than I want that sweet sweet bragging rights on PageSpeed.

After digging in to the source for resources.Concat I couldn’t work out where on earth this random string was coming from. It then occurred to me that it’s not changing each time I rebuild the site, and that maybe it’s a hash?

echo 'bEQ0BoRfV5Pn0rcUvACNXZI9gmzAe39eYv9hEFfjqE6Luv6Yfd7XMJ19s2WYbWbx' | base64 -D | hexdump
0000000 6c 44 34 06 84 5f 57 93 e7 d2 b7 14 bc 00 8d 5d
0000010 92 3d 82 6c c0 7b 7f 5e 62 ff 61 10 57 e3 a8 4e
0000020 8b ba fe 98 7d de d7 30 9d 7d b3 65 98 6d 66 f1
0000030

Yep, it’s a hash, so it seems likely that resources.Fingerprint is responsible for it instead. Removing it reveals that yes, that’s the case. Do I care about SRI? I’m not sure, it’d be a nice to have, assuming it doesn’t mess with caching (ideally, if the user requests a new page, and they have my bundle cached, but the SRI hash doesn’t match, they should re-download it… but I’m not sure if that’s actually what happens?). I can easily remove it for now, but in case I want to add it back later on, it seems easy enough to fingerprint a copy of the resource:

		{{- $bootstrapCss := resources.Get "css/bootstrap.min.css" }}
		{{- $bootstrapFontAwesomeCss := resources.Get "css/font-awesome.min.css" }}
		{{- $bootstrapOverrideCss := resources.Get "css/override.css" }}
		{{- $css := slice $bootstrapCss $bootstrapFontAwesomeCss $bootstrapOverrideCss | resources.Concat "css/darkstrap.css" | resources.Minify }}
		{{- $cssSRI := $css | resources.Fingerprint "sha384" }}
		<link rel="stylesheet" href="{{ $css.Permalink }}" integrity="{{ $cssSRI.Data.Integrity }}" />

This gives me what I want: a predictable resource URL, but with the SRI calculated and Hugo handling everything for me.

That’s got me down to two minor annoyances on my todo list, however in a passing thought I might add a third one: pull the rsync results from the upload process, and fire off CDN cache purge requests for those automatically. Not sure I care about that one either?

Horsham, VIC, Australia fwaggle

Published:


Modified:


Filed under:


Location:

Horsham, VIC, Australia

Navigation: Older Entry