After noticing an oddity while publishing an update to this site, I ended up investigating minification as a way to ensure the results were more consistent.

I use Jekyll to generate this website based on markdown source code. Once this compilation process is complete, a PowerShell script uploads the resulting HTML to my hosting provider.

To make updates as quick and painless as possible, the PowerShell script only uploads files that have changed (this is achieved by keeping a local cache of the files as they’re uploaded, allowing a quick comparison of the SHA1 hashes of the files).

The Problem

The oddity mentioned above was the upload of files that shouldn’t have changed - sometimes there were a lot of extra files uploaded, sometimes only a few.

Investigating the issue, I discovered the generation process for my pages was injecting a significant amount of whitespace into each page.

This whitespace made no difference to the rendering of the page but did result in additional uploads - and I quickly realized that here was a great opportunity to reduce the size of each page, in some cases by a dramatic amount.

The Jekyll minifier

When I first started using Jekyll for the website, I trialed using a Jekyll based minifier to optimize the output - but it lifted the build times from a couple of minutes to most of an hour, so I quickly discarded use.

Since it’s always easier to use a solution you already have, I tried reactivating the Jekyll minifier, only to find that performance was as bad as I remembered, with the build of what’s now a much larger site taking well over 85 minutes.

This time around, I needed something better.

The Node.js minifier

After some research, I found an oft-recommended node.js minifier. People spoke of it well, the GitHub repository was active and it had an offline mode, allowing me to integrate it easily into my existing build pipeline.

I downloaded the tool, worked out how to make it go, and set it running on my HTML output folder with the standard options.

After 45 minutes (yes, minutes), it had processed 168 files … leading me to estimate a 5 1/2 hour runtime to minimize the entire site. This could only be regarded as substantially suboptimal.

Note: The offline mode of this particular tool isn’t their core usage scenario, so I think it would be unfair to call them out for their poor performance in this context.

The Go minifier

With further research, I discovered minify, a streaming command line minifier written in Go. After a quick download, I gave it a try:

I initially thought it had completely failed, because it ran so very quickly. You can see from the timestamps in my (reconstructed) prompt above, that it ran in around one second.

Then a flicker on my screen caught my gaze - it was a File Explorer window, refreshing to show files in the output folder .\minified.

Turns out, it worked.

I needed to tweak the command line a little, but I ended up with a viable solution:

minify.exe .\site -o .\minified --recursive --html-keep-whitespace

This runs in just a couple of seconds, minifying all the HTML files for my site in one go, achieving my goal without extending build time substantially. Minify has a bunch of useful options that you should totally investigate if you’re generating a static site like this one.

Comments

blog comments powered by Disqus
Next Post
Sharpen The Saw #30  19 Feb 2018
Prior Post
Sharpen The Saw #29  12 Feb 2018
Related Posts
Bootstrapping a Psake build  01 Sep 2018
A Productivity Prompt for PowerShell  10 Feb 2018
Test Coverage History  18 Nov 2017
Tracking time  11 Nov 2017
The day my build broke  04 Nov 2017
NuGet and .NET Core  28 Oct 2017
.NET Core Builds  21 Oct 2017
Test Coverage Reporting  07 Oct 2017
Test Coverage with Opencover  30 Sep 2017
NuGet packaging  23 Sep 2017
More powershell posts »
Archives
February 2018
2018