Hakyll CSS Template Compiler

December 9, 2014

Google wasn’t happy with how many render-blocking resources I was loading from pages on this site. It suggested that I inline render-blocking CSS.

I’m not sold that this is ideal. Previously, if a client requested a resource they already had, they wouldn’t necessarily need to re-download the resource. The CSS being used across pages could be cached, so each request would only get the necessary unique data. Other than the initial fetch which would get all the resources, the amount of information exchanged is minimal.

With the CSS inline, this content cannot be cached (across pages), and therefore it is downloaded for each page. While there are fewer requests needed to get a single page, there is redundant information being included in each request.

Anyway, I thought I’d try it out. Hakyll provides a CSS compiler which compresses CSS by removing whitespace, comments, and redundant punctuation. It also provides a template compiler, which allows variable substitution and nesting of templates. However, it doesn’t provide a way to compress CSS inside a template. I took the definition of it’s template compiler and its CSS compiler and combined them:

cssTemplateCompiler :: Compiler (Item Template)
cssTemplateCompiler = cached "Hakyll.Web.Template.cssTemplateCompiler" $
    fmap (readTemplate . compressCss) <$> getResourceString

I made a few other changes in order to make this work. I needed to combine my CSS files, and then include the combined CSS as a partial template in my default template.

I did have one CSS file that I couldn’t inline like this, since it specifies additional resources to fetch (fonts), but this is a Google hosted file, so hopefully they won’t hold it against me. Google suggested that I create a link to this file after rendering, using JavaScript, so that’s in my changes, too.