I was sick as a parrot with a head cold over the weekend. Being unable to do any proper writing, naturally I started messing around with my website. I’ve had some sort of website since around November of 1995, and have kept a more or less regular blog since 2002. Content accumulates, as it turns out. I have about 450,000 words of the stuff here, spread out over about 1,400 separate pages. Over the years I’ve managed it using raw HTML, Movable Type, WordPress, and—most recently—Brandon Mathis’s Octopress. Octopress is a static site generator that combined Jekyll with some nice design and typography, managed with SASS and other tools. I liked it. As you may know, the main virtue of a static site generator is that—unlike, e.g., WordPress—it produces all your pages in a single step. Then you copy (or “deploy” as the kids say these days) them all to your server as fully laid-out plain old HTML files. This means that you can worry much less about server-side performance issues, caching, and all the rest of it, because any modern HTTP server can spit out static HTML pages at a very fast clip indeed. And because there’s no database behind the scenes, and hence no web application interfacing with it to assemble pages on the fly, there are fewer things for malicious visitors to break or hack.

Conversely, the downside of static site generators is that, by definition, they generate your whole site in a single step. Site generation means stitching together style files, page templates (themselves usually split into component pieces), your actual content, and various bells and whistles accomplished with javascript such as tweet buttons or other widgets. Any site indexes, category pages, and so on must be generated, too. The bigger the site, the slower it goes. My 13" MacBook Pro is about a year and a half old and has a 2.5GHz i5 inside. Octopress takes about six and half minutes to generate this site on it.

This kind of performance is par for the course. Most popular static site generators—there are a lot of them—are written in languages like Ruby, Python, or JavaScript, and they don’t exactly fly once the number of pages to be rendered starts to climb into even just the high hundreds. In fairness to these frameworks, the preferred way to write something new is to pick out just the post you’re working on and isolate it, stashing the rest of the site until you are finished writing, previewing, and editing. Then you build the whole site and send it off to the server. Or, even better, you send your changes to the un-built site off to the server, that triggers a build task remotely, and everything is taken care of.

But I am not very responsible about editing. What happens instead is that I write, edit a bit, and then publish a post. Then I read it live on my site and inevitably find typos, ugly phrasing, errors of fact, and all the rest of it. That prompts an annoying cycle of editing, rebuilding … waiting … and re-reading online. I shouldn’t do this. Instead, I should rake isolate[] like a reasonable person and only build when I’m finished. Experience says I will not do this, however. So while Octopress has served me well, and I wish it all the best in its upcoming 3.0 release, over the weekend I started looking around for a faster alternative. While I was at it, I decided to simplify my site’s design as well.

After looking at the current release of Jekyll itself, as well as several of the more promising entries on this list, I settled on Hugo. It’s a relatively young bit of software, developed by Steve Francia. It is written in Go. Its primary appeal for me is that in comparison to the competition it is phenomenally fast. In the Readme, Steve says that “a good rule of thumb is that Hugo takes around 1 millisecond for each piece of content”, and he isn’t kidding. Whereas a basic Jekyll install builds the main part of my site (the blog) in about four minutes, Hugo completed the same job in less than three seconds. I installed the development version of Hugo and spent the weekend learning how it organizes content and manages templates. The basic idea is straightforward, as the structure of your working folder mirrors the structure of the final site. Hugo’s rules about structuring and indexing content types are logical but took a little bit of time to wrap my virus-addled head around. This was a little more complex than average for me because I have inherited an archive structure from very early on in my site’s lifetime. I don’t want to break over a decade’s worth of links for the sake of a new site generator. I figured it out, mostly, though I still have a few questions about whether its possible to get an archive listing outside of the top level of its section.

Other teething issues included getting file names and YAML metadata in the right shape for Hugo, sorting out the templates, and replacing the default design with a new one. I borrowed and modified some CSS from Mark Otto’s Hyde, a theme originally designed for Jekyll sites. Finally, a few of my posts and pages have code excerpts on them and it is nice to have these properly set off and internally highlighted. Right now Hugo doesn’t have a native engine for syntax highlighting, but the development version can hand the job off to Pygments. Steve Francia warns that incorporating the python-driven pygments into the build process will slow it down a lot. It’s true: using it pushed my build time from about four to about seven seconds. If every other post on your site had code excerpts this might become a more serious time cost. But seeing as I was coming from a build time of six or seven minutes, it really wasn’t a problem.

I set up—sorry, I mean, I deployed—the new site on the bus home this afternoon. Let me know if you see any glitches or broken links. I’m pretty happy with it. The new design is simpler than the old one, and a bit friendlier for mobile devices, which as we know are eating the world. Thanks to Steve Francia for a useful and spectacularly fast piece of software. I look forward to following Hugo’s development. In the meantime, I just fixed some typos, rebuilt everything and redeployed it all in less than ten seconds.