Grunt Uncss and Jekyll
Bootstrap, Grunt, Jekyll, Uncss
Front-end frameworks like Bootstrap and Foundation provide a really good way to deliver high-quality modern responsive websites. They take care of the grunt work in terms of layout and common design elements and thereby drastically speed up development time.
I don’t buy the argument that they constrain design. You can style and override these frameworks as required.
They do have a major disadvantage -size. You’re often including (a lot of) rules in your stylesheet that are not used in the current project. Enter Uncss. This article describes how I use Uncss with Grunt on Jekyll projects.
Uncss
Uncss is a node module that removes unused CSS from stylesheets.
On a (fairly typical) recent Jekyll project, Uncss helped me to trim a 190 kB stylesheet down to 32 kB. This is great for user experience, as it speeds up page-load time. It’s probably better for the environment as well, as we’re zapping less bytes down the wire to get the same result.
How Uncss works:
- HTML files are loaded by PhantomJS, a headless browser.
- Stylesheets are parsed by PostCSS - a tool that allows JS plugins to transform styles.
- If a selector is not found in the HTML files, it is removed.
- Remaining rules are converted back to CSS.
You can specify rules to be ignired by Uncss - for example, styles that are added by JavaScript.
Grunt & Uncss
We use Grunt as a front end task runner on our Jekyll projects. No, I don’t care that it’s old-fashioned (!). It performs really well for us and there is no need to change it for a shinier tool in this context.
We use the grunt-uncss grunt task to run Uncss in development.
To install:
Example grunt-uncss Task
We split out grunt tasks into separate files. Contents of a typical config/uncss.js
file:
Grunt Uncss with Jekyll
We manage all our Jekyll builds by means of Grunt tasks. Specifically, we use the grunt-shell
package to build and deploy Jekyll. This provides a convenient way of specifying different configurations for different environments.
We generally include the uncss task on staging and production builds, but not on development builds. Actually we keep the staging build pretty much identical to production for better quality assurance.
Before Grunt Uncss can work, it needs something to work on, which is why the staging grunt task below starts with a Jekyll build ('shell:jekyllNoMap'
). More on the “NoMap” issue later…
Problems with Google Maps
We recently experienced a problem with gulp-uncss
and Google maps. After updating the project, the Uncss task was providing an incomplete style sheet - with no error messages.
Some ideas for debugging:
- Look through the generated (un)css file and search for a style you know should be there: if it isn’t, uncss has encountered a problem
- Make sure your HTML and CSS is valid
- Comment out scripts and go through a process of elimination
In this particular case, the problem was caused by a Google maps call in the <head>
:
With this line commented out, uncss worked perfectly. I have a feeling that this issue is caused by PhantomJS and the fact that the site is running on the http protocol, whereas the link to Google is https.
To be honest, sometimes you can’t justify the time to get to the bottom of issues like this - you just need a quick fix. Fortunately Jekyll makes it pretty easy to define environments by including multiple config files. For example, to build a dev environment you include a _config_dev.yml
config file in your Jekyll build. For example, see our shell.js
config:
The noMap config file _config_no_map.yml
looks like this:
You can then exclude the map script if include-map
returns false:
comments powered by Disqus